1ca76bf8a935ef1da970fbc95869e899120883ba1Fariborz Jahanian//===--- CommentSema.cpp - Doxygen comment semantic analysis --------------===// 28d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko// 38d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko// The LLVM Compiler Infrastructure 48d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko// 58d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko// This file is distributed under the University of Illinois Open Source 68d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko// License. See LICENSE.TXT for details. 78d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko// 88d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko//===----------------------------------------------------------------------===// 98d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 108d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#include "clang/AST/CommentSema.h" 112fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer#include "clang/AST/Attr.h" 12aa58081902ad31927df02e8537d972eabe29d6dfDmitri Gribenko#include "clang/AST/CommentCommandTraits.h" 132fa67efeaf66a9332c30a026dc1c21bef6c33a6cBenjamin Kramer#include "clang/AST/CommentDiagnostic.h" 14a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko#include "clang/AST/Decl.h" 1596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko#include "clang/AST/DeclTemplate.h" 16a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko#include "clang/Basic/SourceManager.h" 171952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko#include "clang/Lex/Preprocessor.h" 181952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko#include "llvm/ADT/SmallString.h" 1955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/ADT/StringSwitch.h" 208d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 218d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenkonamespace clang { 228d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenkonamespace comments { 238d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 24c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenkonamespace { 25c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko#include "clang/AST/CommentHTMLTagsProperties.inc" 26c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko} // unnamed namespace 27c24a76e376a767edc14e60bed716396a84cb127aDmitri Gribenko 28a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri GribenkoSema::Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr, 291952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko DiagnosticsEngine &Diags, CommandTraits &Traits, 301952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko const Preprocessor *PP) : 31aa58081902ad31927df02e8537d972eabe29d6dfDmitri Gribenko Allocator(Allocator), SourceMgr(SourceMgr), Diags(Diags), Traits(Traits), 326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines PP(PP), ThisDeclInfo(nullptr), BriefCommand(nullptr), 336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines HeaderfileCommand(nullptr) { 34a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko} 35a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 36a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenkovoid Sema::setDecl(const Decl *D) { 371ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko if (!D) 381ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko return; 391ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko 401ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko ThisDeclInfo = new (Allocator) DeclInfo; 41bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian ThisDeclInfo->CommentDecl = D; 42651f8ce530ebe6f7f4b67988c3c532a94f097efcDmitri Gribenko ThisDeclInfo->IsFilled = false; 438d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 448d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 458d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri GribenkoParagraphComment *Sema::actOnParagraphComment( 468d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko ArrayRef<InlineContentComment *> Content) { 478d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko return new (Allocator) ParagraphComment(Content); 488d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 498d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 50808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri GribenkoBlockCommandComment *Sema::actOnBlockCommandStart( 51808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko SourceLocation LocBegin, 52808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko SourceLocation LocEnd, 53808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko unsigned CommandID, 54808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko CommandMarkerKind CommandMarker) { 5528c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian BlockCommandComment *BC = new (Allocator) BlockCommandComment(LocBegin, LocEnd, 5628c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian CommandID, 5728c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian CommandMarker); 5828c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian checkContainerDecl(BC); 5928c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return BC; 608d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 618d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 627d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenkovoid Sema::actOnBlockCommandArgs(BlockCommandComment *Command, 637d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko ArrayRef<BlockCommandComment::Argument> Args) { 648d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Command->setArgs(Args); 658d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 668d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 677d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenkovoid Sema::actOnBlockCommandFinish(BlockCommandComment *Command, 687d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko ParagraphComment *Paragraph) { 698d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Command->setParagraph(Paragraph); 70a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko checkBlockCommandEmptyParagraph(Command); 719443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko checkBlockCommandDuplicate(Command); 72651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (ThisDeclInfo) { 73651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // These checks only make sense if the comment is attached to a 74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // declaration. 75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines checkReturnsCommand(Command); 76651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines checkDeprecatedCommand(Command); 77651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 788d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 798d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 80808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri GribenkoParamCommandComment *Sema::actOnParamCommandStart( 81808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko SourceLocation LocBegin, 82808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko SourceLocation LocEnd, 83808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko unsigned CommandID, 84808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko CommandMarkerKind CommandMarker) { 85a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko ParamCommandComment *Command = 86808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko new (Allocator) ParamCommandComment(LocBegin, LocEnd, CommandID, 87808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko CommandMarker); 88a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 898487c524fdfcea3da858fd0af850b4784c8096d0Dmitri Gribenko if (!isFunctionDecl()) 90a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko Diag(Command->getLocation(), 91a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko diag::warn_doc_param_not_attached_to_a_function_decl) 92808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko << CommandMarker 93e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Command->getCommandNameRange(Traits); 94a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 95a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko return Command; 968d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 978d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 982a268f2629b49958427e8eb02f2c3d565be71accFariborz Jahanianvoid Sema::checkFunctionDeclVerbatimLine(const BlockCommandComment *Comment) { 992a268f2629b49958427e8eb02f2c3d565be71accFariborz Jahanian const CommandInfo *Info = Traits.getCommandInfo(Comment->getCommandID()); 10099a7057098c56211e641705e1ff38d4b7c8b309dFariborz Jahanian if (!Info->IsFunctionDeclarationCommand) 10199a7057098c56211e641705e1ff38d4b7c8b309dFariborz Jahanian return; 102b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian 103b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian unsigned DiagSelect; 104b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian switch (Comment->getCommandID()) { 105b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_function: 1062d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian DiagSelect = (!isAnyFunctionDecl() && !isFunctionTemplateDecl())? 1 : 0; 107b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 1082aa5cf412c9a56aba1e3a7b04ca18499a2b83b20Fariborz Jahanian case CommandTraits::KCI_functiongroup: 1092d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian DiagSelect = (!isAnyFunctionDecl() && !isFunctionTemplateDecl())? 2 : 0; 1102aa5cf412c9a56aba1e3a7b04ca18499a2b83b20Fariborz Jahanian break; 111b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_method: 1122aa5cf412c9a56aba1e3a7b04ca18499a2b83b20Fariborz Jahanian DiagSelect = !isObjCMethodDecl() ? 3 : 0; 1132aa5cf412c9a56aba1e3a7b04ca18499a2b83b20Fariborz Jahanian break; 1142aa5cf412c9a56aba1e3a7b04ca18499a2b83b20Fariborz Jahanian case CommandTraits::KCI_methodgroup: 1152aa5cf412c9a56aba1e3a7b04ca18499a2b83b20Fariborz Jahanian DiagSelect = !isObjCMethodDecl() ? 4 : 0; 116b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 117b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_callback: 1182aa5cf412c9a56aba1e3a7b04ca18499a2b83b20Fariborz Jahanian DiagSelect = !isFunctionPointerVarDecl() ? 5 : 0; 119b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 120b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian default: 121b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 0; 122b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 123b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian } 12488f070f99f7f352e294eed212fdf7a23c0815fe2Fariborz Jahanian if (DiagSelect) 12588f070f99f7f352e294eed212fdf7a23c0815fe2Fariborz Jahanian Diag(Comment->getLocation(), diag::warn_doc_function_method_decl_mismatch) 12688f070f99f7f352e294eed212fdf7a23c0815fe2Fariborz Jahanian << Comment->getCommandMarker() 12788f070f99f7f352e294eed212fdf7a23c0815fe2Fariborz Jahanian << (DiagSelect-1) << (DiagSelect-1) 1282a268f2629b49958427e8eb02f2c3d565be71accFariborz Jahanian << Comment->getSourceRange(); 1292a268f2629b49958427e8eb02f2c3d565be71accFariborz Jahanian} 130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 13128c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanianvoid Sema::checkContainerDeclVerbatimLine(const BlockCommandComment *Comment) { 13228c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian const CommandInfo *Info = Traits.getCommandInfo(Comment->getCommandID()); 133b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian if (!Info->IsRecordLikeDeclarationCommand) 13428c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return; 135b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian unsigned DiagSelect; 136b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian switch (Comment->getCommandID()) { 137b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_class: 1382d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian DiagSelect = (!isClassOrStructDecl() && !isClassTemplateDecl()) ? 1 : 0; 139dbed7cceb8b453cc0ef78cc83f5466d5268037baFariborz Jahanian // Allow @class command on @interface declarations. 140dbed7cceb8b453cc0ef78cc83f5466d5268037baFariborz Jahanian // FIXME. Currently, \class and @class are indistinguishable. So, 141dbed7cceb8b453cc0ef78cc83f5466d5268037baFariborz Jahanian // \class is also allowed on an @interface declaration 142dbed7cceb8b453cc0ef78cc83f5466d5268037baFariborz Jahanian if (DiagSelect && Comment->getCommandMarker() && isObjCInterfaceDecl()) 143dbed7cceb8b453cc0ef78cc83f5466d5268037baFariborz Jahanian DiagSelect = 0; 144b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 145b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_interface: 146b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = !isObjCInterfaceDecl() ? 2 : 0; 147b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 148b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_protocol: 149b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = !isObjCProtocolDecl() ? 3 : 0; 150b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 151b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_struct: 152b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = !isClassOrStructDecl() ? 4 : 0; 153b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 154b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_union: 155b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = !isUnionDecl() ? 5 : 0; 156b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 157b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian default: 158b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 0; 159b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 160b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian } 16128c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (DiagSelect) 16228c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian Diag(Comment->getLocation(), diag::warn_doc_api_container_decl_mismatch) 16328c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian << Comment->getCommandMarker() 16428c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian << (DiagSelect-1) << (DiagSelect-1) 16528c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian << Comment->getSourceRange(); 16628c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian} 16728c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian 16828c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanianvoid Sema::checkContainerDecl(const BlockCommandComment *Comment) { 16928c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian const CommandInfo *Info = Traits.getCommandInfo(Comment->getCommandID()); 170b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian if (!Info->IsRecordLikeDetailCommand || isRecordLikeDecl()) 17128c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return; 172b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian unsigned DiagSelect; 173b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian switch (Comment->getCommandID()) { 174b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_classdesign: 175b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 1; 176b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 177b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_coclass: 178b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 2; 179b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 180b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_dependency: 181b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 3; 182b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 183b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_helper: 184b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 4; 185b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 186b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_helperclass: 187b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 5; 188b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 189b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_helps: 190b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 6; 191b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 192b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_instancesize: 193b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 7; 194b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 195b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_ownership: 196b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 8; 197b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 198b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_performance: 199b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 9; 200b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 201b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_security: 202b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 10; 203b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 204b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian case CommandTraits::KCI_superclass: 205b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 11; 206b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 207b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian default: 208b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian DiagSelect = 0; 209b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian break; 210b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian } 21128c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (DiagSelect) 21228c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian Diag(Comment->getLocation(), diag::warn_doc_container_decl_mismatch) 21328c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian << Comment->getCommandMarker() 21428c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian << (DiagSelect-1) 21528c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian << Comment->getSourceRange(); 21628c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian} 2172a268f2629b49958427e8eb02f2c3d565be71accFariborz Jahanian 218144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer/// \brief Turn a string into the corresponding PassDirection or -1 if it's not 219144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer/// valid. 220144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramerstatic int getParamPassDirection(StringRef Arg) { 221144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer return llvm::StringSwitch<int>(Arg) 222144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer .Case("[in]", ParamCommandComment::In) 223144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer .Case("[out]", ParamCommandComment::Out) 224144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer .Cases("[in,out]", "[out,in]", ParamCommandComment::InOut) 225144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer .Default(-1); 226144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer} 227144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer 2287d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenkovoid Sema::actOnParamCommandDirectionArg(ParamCommandComment *Command, 2297d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko SourceLocation ArgLocBegin, 2307d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko SourceLocation ArgLocEnd, 2317d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko StringRef Arg) { 232a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko std::string ArgLower = Arg.lower(); 233144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer int Direction = getParamPassDirection(ArgLower); 234a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 235144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer if (Direction == -1) { 236144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer // Try again with whitespace removed. 237144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer ArgLower.erase( 238144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer std::remove_if(ArgLower.begin(), ArgLower.end(), clang::isWhitespace), 239144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer ArgLower.end()); 240144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer Direction = getParamPassDirection(ArgLower); 241a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 242a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko SourceRange ArgRange(ArgLocBegin, ArgLocEnd); 243144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer if (Direction != -1) { 244144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer const char *FixedName = ParamCommandComment::getDirectionAsString( 245144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer (ParamCommandComment::PassDirection)Direction); 246a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko Diag(ArgLocBegin, diag::warn_doc_param_spaces_in_direction) 247144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer << ArgRange << FixItHint::CreateReplacement(ArgRange, FixedName); 248144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer } else { 249144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer Diag(ArgLocBegin, diag::warn_doc_param_invalid_direction) << ArgRange; 250144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer Direction = ParamCommandComment::In; // Sane fall back. 251144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer } 2528d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko } 253144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer Command->setDirection((ParamCommandComment::PassDirection)Direction, 254144879a48fb91cd3685fa1fadd9cb5851895759aBenjamin Kramer /*Explicit=*/true); 255a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko} 256a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 2577d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenkovoid Sema::actOnParamCommandParamNameArg(ParamCommandComment *Command, 2587d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko SourceLocation ArgLocBegin, 2597d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko SourceLocation ArgLocEnd, 2607d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko StringRef Arg) { 261a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko // Parser will not feed us more arguments than needed. 2620eaf69d9a10149f0f344238183915912c2dca392Dmitri Gribenko assert(Command->getNumArgs() == 0); 263a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 264a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko if (!Command->isDirectionExplicit()) { 265a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko // User didn't provide a direction argument. 266a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko Command->setDirection(ParamCommandComment::In, /* Explicit = */ false); 267a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 268a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko typedef BlockCommandComment::Argument Argument; 269a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko Argument *A = new (Allocator) Argument(SourceRange(ArgLocBegin, 270a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko ArgLocEnd), 271a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko Arg); 272a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko Command->setArgs(llvm::makeArrayRef(A, 1)); 2738d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 2748d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 2757d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenkovoid Sema::actOnParamCommandFinish(ParamCommandComment *Command, 2767d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko ParagraphComment *Paragraph) { 2778d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Command->setParagraph(Paragraph); 278a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko checkBlockCommandEmptyParagraph(Command); 2798d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 2808d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 281808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri GribenkoTParamCommandComment *Sema::actOnTParamCommandStart( 282808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko SourceLocation LocBegin, 283808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko SourceLocation LocEnd, 284808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko unsigned CommandID, 285808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko CommandMarkerKind CommandMarker) { 28696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko TParamCommandComment *Command = 287808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko new (Allocator) TParamCommandComment(LocBegin, LocEnd, CommandID, 288808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko CommandMarker); 28996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 29004bf29eb1b197e0a103139ab5d63b0b97432f004Dmitri Gribenko if (!isTemplateOrSpecialization()) 29196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Diag(Command->getLocation(), 29296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko diag::warn_doc_tparam_not_attached_to_a_template_decl) 293808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko << CommandMarker 294e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Command->getCommandNameRange(Traits); 29596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 29696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return Command; 29796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko} 29896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 2997d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenkovoid Sema::actOnTParamCommandParamNameArg(TParamCommandComment *Command, 3007d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko SourceLocation ArgLocBegin, 3017d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko SourceLocation ArgLocEnd, 3027d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko StringRef Arg) { 30396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko // Parser will not feed us more arguments than needed. 30496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko assert(Command->getNumArgs() == 0); 30596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 30696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko typedef BlockCommandComment::Argument Argument; 30796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Argument *A = new (Allocator) Argument(SourceRange(ArgLocBegin, 30896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko ArgLocEnd), 30996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Arg); 31096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Command->setArgs(llvm::makeArrayRef(A, 1)); 31196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 31204bf29eb1b197e0a103139ab5d63b0b97432f004Dmitri Gribenko if (!isTemplateOrSpecialization()) { 31396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko // We already warned that this \\tparam is not attached to a template decl. 3147d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko return; 31596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko } 31696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 3171ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko const TemplateParameterList *TemplateParameters = 3181ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko ThisDeclInfo->TemplateParameters; 31996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko SmallVector<unsigned, 2> Position; 32096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (resolveTParamReference(Arg, TemplateParameters, &Position)) { 32196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Command->setPosition(copyArray(llvm::makeArrayRef(Position))); 322471b52aaab1d175ddad7c24d825dbf0582a1767eBenjamin Kramer TParamCommandComment *&PrevCommand = TemplateParameterDocs[Arg]; 323471b52aaab1d175ddad7c24d825dbf0582a1767eBenjamin Kramer if (PrevCommand) { 32496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko SourceRange ArgRange(ArgLocBegin, ArgLocEnd); 32596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Diag(ArgLocBegin, diag::warn_doc_tparam_duplicate) 32696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko << Arg << ArgRange; 32796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Diag(PrevCommand->getLocation(), diag::note_doc_tparam_previous) 32896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko << PrevCommand->getParamNameRange(); 32996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko } 330471b52aaab1d175ddad7c24d825dbf0582a1767eBenjamin Kramer PrevCommand = Command; 3317d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko return; 33296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko } 33396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 33496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko SourceRange ArgRange(ArgLocBegin, ArgLocEnd); 33596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Diag(ArgLocBegin, diag::warn_doc_tparam_not_found) 33696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko << Arg << ArgRange; 33796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 33896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (!TemplateParameters || TemplateParameters->size() == 0) 3397d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko return; 34096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 34196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko StringRef CorrectedName; 34296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (TemplateParameters->size() == 1) { 34396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const NamedDecl *Param = TemplateParameters->getParam(0); 34496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const IdentifierInfo *II = Param->getIdentifier(); 34596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (II) 34696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko CorrectedName = II->getName(); 34796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko } else { 34896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko CorrectedName = correctTypoInTParamReference(Arg, TemplateParameters); 34996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko } 35096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 35196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (!CorrectedName.empty()) { 35296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Diag(ArgLocBegin, diag::note_doc_tparam_name_suggestion) 35396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko << CorrectedName 35496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko << FixItHint::CreateReplacement(ArgRange, CorrectedName); 35596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko } 35696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 3577d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko return; 35896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko} 35996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 3607d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenkovoid Sema::actOnTParamCommandFinish(TParamCommandComment *Command, 3617d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenko ParagraphComment *Paragraph) { 36296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Command->setParagraph(Paragraph); 36396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko checkBlockCommandEmptyParagraph(Command); 36496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko} 36596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 3668d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri GribenkoInlineCommandComment *Sema::actOnInlineCommand(SourceLocation CommandLocBegin, 3678d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko SourceLocation CommandLocEnd, 368e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko unsigned CommandID) { 3698d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko ArrayRef<InlineCommandComment::Argument> Args; 370e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko StringRef CommandName = Traits.getCommandInfo(CommandID)->Name; 3712d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko return new (Allocator) InlineCommandComment( 3722d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko CommandLocBegin, 3732d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko CommandLocEnd, 374e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko CommandID, 3752d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko getInlineCommandRenderKind(CommandName), 3762d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko Args); 3778d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 3788d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 3798d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri GribenkoInlineCommandComment *Sema::actOnInlineCommand(SourceLocation CommandLocBegin, 3808d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko SourceLocation CommandLocEnd, 381e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko unsigned CommandID, 3828d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko SourceLocation ArgLocBegin, 3838d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko SourceLocation ArgLocEnd, 3848d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko StringRef Arg) { 3858d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko typedef InlineCommandComment::Argument Argument; 3868d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Argument *A = new (Allocator) Argument(SourceRange(ArgLocBegin, 3878d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko ArgLocEnd), 3888d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Arg); 389e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko StringRef CommandName = Traits.getCommandInfo(CommandID)->Name; 3908d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 3912d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko return new (Allocator) InlineCommandComment( 3922d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko CommandLocBegin, 3932d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko CommandLocEnd, 394e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko CommandID, 3952d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko getInlineCommandRenderKind(CommandName), 3962d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko llvm::makeArrayRef(A, 1)); 3978d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 3988d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 3998d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri GribenkoInlineContentComment *Sema::actOnUnknownCommand(SourceLocation LocBegin, 4008d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko SourceLocation LocEnd, 401b0b8a96df25660cbdbf35d23c3ff5887c33f82f9Dmitri Gribenko StringRef CommandName) { 402b0b8a96df25660cbdbf35d23c3ff5887c33f82f9Dmitri Gribenko unsigned CommandID = Traits.registerUnknownCommand(CommandName)->getID(); 403b0b8a96df25660cbdbf35d23c3ff5887c33f82f9Dmitri Gribenko return actOnUnknownCommand(LocBegin, LocEnd, CommandID); 404b0b8a96df25660cbdbf35d23c3ff5887c33f82f9Dmitri Gribenko} 405b0b8a96df25660cbdbf35d23c3ff5887c33f82f9Dmitri Gribenko 406b0b8a96df25660cbdbf35d23c3ff5887c33f82f9Dmitri GribenkoInlineContentComment *Sema::actOnUnknownCommand(SourceLocation LocBegin, 407b0b8a96df25660cbdbf35d23c3ff5887c33f82f9Dmitri Gribenko SourceLocation LocEnd, 408b0b8a96df25660cbdbf35d23c3ff5887c33f82f9Dmitri Gribenko unsigned CommandID) { 4098d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko ArrayRef<InlineCommandComment::Argument> Args; 4102d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko return new (Allocator) InlineCommandComment( 411e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko LocBegin, LocEnd, CommandID, 4122d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko InlineCommandComment::RenderNormal, 4132d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko Args); 4148d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 4158d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 4168d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri GribenkoTextComment *Sema::actOnText(SourceLocation LocBegin, 4178d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko SourceLocation LocEnd, 4188d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko StringRef Text) { 4198d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko return new (Allocator) TextComment(LocBegin, LocEnd, Text); 4208d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 4218d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 4228d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri GribenkoVerbatimBlockComment *Sema::actOnVerbatimBlockStart(SourceLocation Loc, 423e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko unsigned CommandID) { 424e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko StringRef CommandName = Traits.getCommandInfo(CommandID)->Name; 4258d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko return new (Allocator) VerbatimBlockComment( 4268d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Loc, 427e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko Loc.getLocWithOffset(1 + CommandName.size()), 428e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko CommandID); 4298d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 4308d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 4318d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri GribenkoVerbatimBlockLineComment *Sema::actOnVerbatimBlockLine(SourceLocation Loc, 4328d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko StringRef Text) { 4338d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko return new (Allocator) VerbatimBlockLineComment(Loc, Text); 4348d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 4358d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 4367d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenkovoid Sema::actOnVerbatimBlockFinish( 4378d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko VerbatimBlockComment *Block, 4388d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko SourceLocation CloseNameLocBegin, 4398d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko StringRef CloseName, 4408d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko ArrayRef<VerbatimBlockLineComment *> Lines) { 4418d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Block->setCloseName(CloseName, CloseNameLocBegin); 4428d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Block->setLines(Lines); 4438d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 4448d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 4458d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri GribenkoVerbatimLineComment *Sema::actOnVerbatimLine(SourceLocation LocBegin, 446e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko unsigned CommandID, 4478d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko SourceLocation TextBegin, 4488d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko StringRef Text) { 449bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian VerbatimLineComment *VL = new (Allocator) VerbatimLineComment( 4508d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko LocBegin, 4518d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko TextBegin.getLocWithOffset(Text.size()), 452e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko CommandID, 4538d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko TextBegin, 4548d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Text); 455bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian checkFunctionDeclVerbatimLine(VL); 45628c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian checkContainerDeclVerbatimLine(VL); 457bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian return VL; 4588d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 4598d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 4603f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri GribenkoHTMLStartTagComment *Sema::actOnHTMLStartTagStart(SourceLocation LocBegin, 4613f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko StringRef TagName) { 4623f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko return new (Allocator) HTMLStartTagComment(LocBegin, TagName); 4638d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 4648d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 4657d9b51107999c1c1fada7319c4687fe570eb2c0bDmitri Gribenkovoid Sema::actOnHTMLStartTagFinish( 4663f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko HTMLStartTagComment *Tag, 4673f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko ArrayRef<HTMLStartTagComment::Attribute> Attrs, 468a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko SourceLocation GreaterLoc, 469a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko bool IsSelfClosing) { 4708d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Tag->setAttrs(Attrs); 4718d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko Tag->setGreaterLoc(GreaterLoc); 472a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko if (IsSelfClosing) 473a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko Tag->setSelfClosing(); 4743f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko else if (!isHTMLEndTagForbidden(Tag->getTagName())) 475a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko HTMLOpenTags.push_back(Tag); 4768d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 4778d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 4783f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri GribenkoHTMLEndTagComment *Sema::actOnHTMLEndTag(SourceLocation LocBegin, 4793f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko SourceLocation LocEnd, 4803f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko StringRef TagName) { 4813f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko HTMLEndTagComment *HET = 4823f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko new (Allocator) HTMLEndTagComment(LocBegin, LocEnd, TagName); 4833f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko if (isHTMLEndTagForbidden(TagName)) { 4843f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko Diag(HET->getLocation(), diag::warn_doc_html_end_forbidden) 4853f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko << TagName << HET->getSourceRange(); 4866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines HET->setIsMalformed(); 4873f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko return HET; 4883d986980bd02594b1a5aa7b9f9f68d201621ced7Dmitri Gribenko } 4893d986980bd02594b1a5aa7b9f9f68d201621ced7Dmitri Gribenko 490a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko bool FoundOpen = false; 4913f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko for (SmallVectorImpl<HTMLStartTagComment *>::const_reverse_iterator 492a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko I = HTMLOpenTags.rbegin(), E = HTMLOpenTags.rend(); 493a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko I != E; ++I) { 494a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko if ((*I)->getTagName() == TagName) { 495a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko FoundOpen = true; 496a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko break; 497a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 498a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 499a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko if (!FoundOpen) { 5003f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko Diag(HET->getLocation(), diag::warn_doc_html_end_unbalanced) 5013f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko << HET->getSourceRange(); 5026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines HET->setIsMalformed(); 5033f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko return HET; 504a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 505a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 506a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko while (!HTMLOpenTags.empty()) { 5076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines HTMLStartTagComment *HST = HTMLOpenTags.pop_back_val(); 5083f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko StringRef LastNotClosedTagName = HST->getTagName(); 5096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (LastNotClosedTagName == TagName) { 5106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // If the start tag is malformed, end tag is malformed as well. 5116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (HST->isMalformed()) 5126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines HET->setIsMalformed(); 513a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko break; 5146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 515a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 5163f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko if (isHTMLEndTagOptional(LastNotClosedTagName)) 517a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko continue; 518a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 519a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko bool OpenLineInvalid; 520a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko const unsigned OpenLine = SourceMgr.getPresumedLineNumber( 5213f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko HST->getLocation(), 522a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko &OpenLineInvalid); 523a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko bool CloseLineInvalid; 524a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko const unsigned CloseLine = SourceMgr.getPresumedLineNumber( 5253f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko HET->getLocation(), 526a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko &CloseLineInvalid); 527a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 5286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (OpenLineInvalid || CloseLineInvalid || OpenLine == CloseLine) { 5293f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko Diag(HST->getLocation(), diag::warn_doc_html_start_end_mismatch) 5303f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko << HST->getTagName() << HET->getTagName() 5313f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko << HST->getSourceRange() << HET->getSourceRange(); 5326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines HST->setIsMalformed(); 5336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } else { 5343f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko Diag(HST->getLocation(), diag::warn_doc_html_start_end_mismatch) 5353f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko << HST->getTagName() << HET->getTagName() 5363f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko << HST->getSourceRange(); 5373f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko Diag(HET->getLocation(), diag::note_doc_html_end_tag) 5383f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko << HET->getSourceRange(); 5396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines HST->setIsMalformed(); 540a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 541a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 542a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 5433f38bf2d441fac379c427f86153fbb0cb41256c6Dmitri Gribenko return HET; 5448d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 5458d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 5468d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri GribenkoFullComment *Sema::actOnFullComment( 5478d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko ArrayRef<BlockContentComment *> Blocks) { 548749ace614b6ea1ae11d194a60b18e1e43e1db243Fariborz Jahanian FullComment *FC = new (Allocator) FullComment(Blocks, ThisDeclInfo); 5499edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko resolveParamCommandIndexes(FC); 5506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Complain about HTML tags that are not closed. 5526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines while (!HTMLOpenTags.empty()) { 5536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines HTMLStartTagComment *HST = HTMLOpenTags.pop_back_val(); 5546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (isHTMLEndTagOptional(HST->getTagName())) 5556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines continue; 5566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Diag(HST->getLocation(), diag::warn_doc_html_missing_end_tag) 5586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines << HST->getTagName() << HST->getSourceRange(); 5596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines HST->setIsMalformed(); 5606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 5616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5629edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko return FC; 5638d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} 5648d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 565a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenkovoid Sema::checkBlockCommandEmptyParagraph(BlockCommandComment *Command) { 566abcf0dccc9cd4c802f4e7797bf452c6808d2226fDmitri Gribenko if (Traits.getCommandInfo(Command->getCommandID())->IsEmptyParagraphAllowed) 567abcf0dccc9cd4c802f4e7797bf452c6808d2226fDmitri Gribenko return; 568abcf0dccc9cd4c802f4e7797bf452c6808d2226fDmitri Gribenko 569a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko ParagraphComment *Paragraph = Command->getParagraph(); 570a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko if (Paragraph->isWhitespace()) { 571a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko SourceLocation DiagLoc; 5720eaf69d9a10149f0f344238183915912c2dca392Dmitri Gribenko if (Command->getNumArgs() > 0) 5730eaf69d9a10149f0f344238183915912c2dca392Dmitri Gribenko DiagLoc = Command->getArgRange(Command->getNumArgs() - 1).getEnd(); 574a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko if (!DiagLoc.isValid()) 575e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko DiagLoc = Command->getCommandNameRange(Traits).getEnd(); 576a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko Diag(DiagLoc, diag::warn_doc_block_command_empty_paragraph) 577808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko << Command->getCommandMarker() 578e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Command->getCommandName(Traits) 579a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko << Command->getSourceRange(); 580a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 581a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko} 582a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 58389ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenkovoid Sema::checkReturnsCommand(const BlockCommandComment *Command) { 584e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko if (!Traits.getCommandInfo(Command->getCommandID())->IsReturnsCommand) 58589ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko return; 586651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 587651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(ThisDeclInfo && "should not call this check on a bare comment"); 588651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 58989ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko if (isFunctionDecl()) { 590651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (ThisDeclInfo->ReturnType->isVoidType()) { 59189ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko unsigned DiagKind; 592bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian switch (ThisDeclInfo->CommentDecl->getKind()) { 59389ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko default: 59488815f3f81361692dd281000e3e46bf163b2f28bDmitri Gribenko if (ThisDeclInfo->IsObjCMethod) 59588815f3f81361692dd281000e3e46bf163b2f28bDmitri Gribenko DiagKind = 3; 59688815f3f81361692dd281000e3e46bf163b2f28bDmitri Gribenko else 59788815f3f81361692dd281000e3e46bf163b2f28bDmitri Gribenko DiagKind = 0; 59889ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko break; 59989ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko case Decl::CXXConstructor: 60089ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko DiagKind = 1; 60189ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko break; 60289ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko case Decl::CXXDestructor: 60389ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko DiagKind = 2; 60489ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko break; 60589ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko } 60689ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko Diag(Command->getLocation(), 60789ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko diag::warn_doc_returns_attached_to_a_void_function) 608808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko << Command->getCommandMarker() 609e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Command->getCommandName(Traits) 61089ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko << DiagKind 61189ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko << Command->getSourceRange(); 61289ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko } 61389ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko return; 61489ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko } 615664e860beb2550bef24fb8946192f61648a71d7fFariborz Jahanian else if (isObjCPropertyDecl()) 616664e860beb2550bef24fb8946192f61648a71d7fFariborz Jahanian return; 617651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 61889ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko Diag(Command->getLocation(), 61989ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko diag::warn_doc_returns_not_attached_to_a_function_decl) 620808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko << Command->getCommandMarker() 621e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Command->getCommandName(Traits) 62289ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko << Command->getSourceRange(); 62389ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko} 62489ab7d0012ffe02a335b765eeb9b48977a5ecd79Dmitri Gribenko 6259443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenkovoid Sema::checkBlockCommandDuplicate(const BlockCommandComment *Command) { 626e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko const CommandInfo *Info = Traits.getCommandInfo(Command->getCommandID()); 6276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const BlockCommandComment *PrevCommand = nullptr; 628e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko if (Info->IsBriefCommand) { 6299443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko if (!BriefCommand) { 6309443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko BriefCommand = Command; 6319443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko return; 6329443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko } 6339443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko PrevCommand = BriefCommand; 634f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian } else if (Info->IsHeaderfileCommand) { 635f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian if (!HeaderfileCommand) { 636f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian HeaderfileCommand = Command; 637f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian return; 638f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian } 639f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian PrevCommand = HeaderfileCommand; 6409443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko } else { 6419443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko // We don't want to check this command for duplicates. 6429443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko return; 6439443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko } 644e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko StringRef CommandName = Command->getCommandName(Traits); 645e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko StringRef PrevCommandName = PrevCommand->getCommandName(Traits); 6469443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko Diag(Command->getLocation(), diag::warn_doc_block_command_duplicate) 647808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko << Command->getCommandMarker() 648e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << CommandName 6499443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko << Command->getSourceRange(); 650e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko if (CommandName == PrevCommandName) 6519443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko Diag(PrevCommand->getLocation(), diag::note_doc_block_command_previous) 652808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko << PrevCommand->getCommandMarker() 653e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << PrevCommandName 654e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << PrevCommand->getSourceRange(); 6559443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko else 6569443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko Diag(PrevCommand->getLocation(), 6579443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko diag::note_doc_block_command_previous_alias) 658808383d2d6d58a7c7db85f8c7618fb74d821309fDmitri Gribenko << PrevCommand->getCommandMarker() 659e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << PrevCommandName 660e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << CommandName; 6619443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko} 6629443c57150e870e308406e1e4e6d9d64712b417eDmitri Gribenko 6630bd9838751384181ff387f2fb346896792b89617Dmitri Gribenkovoid Sema::checkDeprecatedCommand(const BlockCommandComment *Command) { 6640bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko if (!Traits.getCommandInfo(Command->getCommandID())->IsDeprecatedCommand) 6650bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko return; 6660bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko 667651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(ThisDeclInfo && "should not call this check on a bare comment"); 668651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 669bf967be66ea8c51b66c61659c23240f762a56dbeFariborz Jahanian const Decl *D = ThisDeclInfo->CommentDecl; 6700bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko if (!D) 6710bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko return; 6720bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko 6730bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko if (D->hasAttr<DeprecatedAttr>() || 6740bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko D->hasAttr<AvailabilityAttr>() || 6750bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko D->hasAttr<UnavailableAttr>()) 6760bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko return; 6770bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko 6780bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko Diag(Command->getLocation(), 6790bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko diag::warn_doc_deprecated_not_sync) 6800bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko << Command->getSourceRange(); 6810bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko 6820bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko // Try to emit a fixit with a deprecation attribute. 6830bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 6840bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko // Don't emit a Fix-It for non-member function definitions. GCC does not 6850bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko // accept attributes on them. 6860bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko const DeclContext *Ctx = FD->getDeclContext(); 6870bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko if ((!Ctx || !Ctx->isRecord()) && 6880bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko FD->doesThisDeclarationHaveABody()) 6890bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko return; 6900bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko 6911952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko StringRef AttributeSpelling = "__attribute__((deprecated))"; 6921952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko if (PP) { 6931952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko TokenValue Tokens[] = { 6941952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko tok::kw___attribute, tok::l_paren, tok::l_paren, 6951952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko PP->getIdentifierInfo("deprecated"), 6961952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko tok::r_paren, tok::r_paren 6971952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko }; 6981952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko StringRef MacroName = PP->getLastMacroWithSpelling(FD->getLocation(), 6991952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko Tokens); 7001952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko if (!MacroName.empty()) 7011952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko AttributeSpelling = MacroName; 7021952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko } 7031952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko 7041952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko SmallString<64> TextToInsert(" "); 7051952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko TextToInsert += AttributeSpelling; 7060bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko Diag(FD->getLocEnd(), 7070bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko diag::note_add_deprecation_attr) 7080bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko << FixItHint::CreateInsertion(FD->getLocEnd().getLocWithOffset(1), 7091952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko TextToInsert); 7100bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko } 7110bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko} 7120bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko 7139edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenkovoid Sema::resolveParamCommandIndexes(const FullComment *FC) { 7149edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko if (!isFunctionDecl()) { 7159edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // We already warned that \\param commands are not attached to a function 7169edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // decl. 7179edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko return; 7189edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko } 7199edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko 720cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallVector<ParamCommandComment *, 8> UnresolvedParamCommands; 7219edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko 7229edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // Comment AST nodes that correspond to \c ParamVars for which we have 7239edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // found a \\param command or NULL if no documentation was found so far. 724cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallVector<ParamCommandComment *, 8> ParamVarDocs; 7259edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko 7269edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko ArrayRef<const ParmVarDecl *> ParamVars = getParamVars(); 7276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ParamVarDocs.resize(ParamVars.size(), nullptr); 7289edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko 7299edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // First pass over all \\param commands: resolve all parameter names. 7309edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko for (Comment::child_iterator I = FC->child_begin(), E = FC->child_end(); 7319edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko I != E; ++I) { 7329edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko ParamCommandComment *PCC = dyn_cast<ParamCommandComment>(*I); 7339edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko if (!PCC || !PCC->hasParamName()) 7349edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko continue; 735262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian StringRef ParamName = PCC->getParamNameAsWritten(); 7369edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko 7379edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // Check that referenced parameter name is in the function decl. 7389edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko const unsigned ResolvedParamIndex = resolveParmVarReference(ParamName, 7399edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko ParamVars); 740c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko if (ResolvedParamIndex == ParamCommandComment::VarArgParamIndex) { 741c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko PCC->setIsVarArgParam(); 742c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko continue; 743c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko } 7449edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko if (ResolvedParamIndex == ParamCommandComment::InvalidParamIndex) { 7459edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko UnresolvedParamCommands.push_back(PCC); 7469edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko continue; 7479edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko } 7489edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko PCC->setParamIndex(ResolvedParamIndex); 7499edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko if (ParamVarDocs[ResolvedParamIndex]) { 7509edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko SourceRange ArgRange = PCC->getParamNameRange(); 7519edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko Diag(ArgRange.getBegin(), diag::warn_doc_param_duplicate) 7529edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko << ParamName << ArgRange; 7539edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko ParamCommandComment *PrevCommand = ParamVarDocs[ResolvedParamIndex]; 7549edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko Diag(PrevCommand->getLocation(), diag::note_doc_param_previous) 7559edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko << PrevCommand->getParamNameRange(); 7569edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko } 7579edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko ParamVarDocs[ResolvedParamIndex] = PCC; 7589edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko } 7599edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko 7609edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // Find parameter declarations that have no corresponding \\param. 761cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko SmallVector<const ParmVarDecl *, 8> OrphanedParamDecls; 7629edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko for (unsigned i = 0, e = ParamVarDocs.size(); i != e; ++i) { 7639edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko if (!ParamVarDocs[i]) 7649edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko OrphanedParamDecls.push_back(ParamVars[i]); 7659edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko } 7669edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko 7679edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // Second pass over unresolved \\param commands: do typo correction. 7689edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // Suggest corrections from a set of parameter declarations that have no 7699edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // corresponding \\param. 7709edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko for (unsigned i = 0, e = UnresolvedParamCommands.size(); i != e; ++i) { 7719edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko const ParamCommandComment *PCC = UnresolvedParamCommands[i]; 7729edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko 7739edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko SourceRange ArgRange = PCC->getParamNameRange(); 774262e60c1ccb5197e8e2ea49ada1196ed65183734Fariborz Jahanian StringRef ParamName = PCC->getParamNameAsWritten(); 7759edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko Diag(ArgRange.getBegin(), diag::warn_doc_param_not_found) 7769edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko << ParamName << ArgRange; 7779edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko 7789edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // All parameters documented -- can't suggest a correction. 7799edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko if (OrphanedParamDecls.size() == 0) 7809edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko continue; 7819edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko 7829edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko unsigned CorrectedParamIndex = ParamCommandComment::InvalidParamIndex; 7839edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko if (OrphanedParamDecls.size() == 1) { 7849edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // If one parameter is not documented then that parameter is the only 7859edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // possible suggestion. 7869edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko CorrectedParamIndex = 0; 7879edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko } else { 7889edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko // Do typo correction. 7899edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko CorrectedParamIndex = correctTypoInParmVarReference(ParamName, 7909edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko OrphanedParamDecls); 7919edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko } 7929edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko if (CorrectedParamIndex != ParamCommandComment::InvalidParamIndex) { 7939edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko const ParmVarDecl *CorrectedPVD = OrphanedParamDecls[CorrectedParamIndex]; 7949edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko if (const IdentifierInfo *CorrectedII = CorrectedPVD->getIdentifier()) 7959edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko Diag(ArgRange.getBegin(), diag::note_doc_param_name_suggestion) 7969edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko << CorrectedII->getName() 7979edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko << FixItHint::CreateReplacement(ArgRange, CorrectedII->getName()); 7989edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko } 7999edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko } 8009edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko} 8019edd2c8a2ff6c6326ff2d5b081929e4baaa798edDmitri Gribenko 8028487c524fdfcea3da858fd0af850b4784c8096d0Dmitri Gribenkobool Sema::isFunctionDecl() { 8031ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko if (!ThisDeclInfo) 8041ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko return false; 8051ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko if (!ThisDeclInfo->IsFilled) 80600c59f7ed2814f67d6d7e844479ea99eca9e55efDmitri Gribenko inspectThisDecl(); 807af19a6aaa2959ef5e76f19d51e87ef523bdeeddeDmitri Gribenko return ThisDeclInfo->getKind() == DeclInfo::FunctionKind; 8088487c524fdfcea3da858fd0af850b4784c8096d0Dmitri Gribenko} 80999a7057098c56211e641705e1ff38d4b7c8b309dFariborz Jahanian 810eb8f69f094e95d0132e4a6817a2111ad188ab087Fariborz Jahanianbool Sema::isAnyFunctionDecl() { 811eb8f69f094e95d0132e4a6817a2111ad188ab087Fariborz Jahanian return isFunctionDecl() && ThisDeclInfo->CurrentDecl && 812eb8f69f094e95d0132e4a6817a2111ad188ab087Fariborz Jahanian isa<FunctionDecl>(ThisDeclInfo->CurrentDecl); 813eb8f69f094e95d0132e4a6817a2111ad188ab087Fariborz Jahanian} 814c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko 815c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenkobool Sema::isFunctionOrMethodVariadic() { 816651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!isAnyFunctionDecl() && !isObjCMethodDecl() && !isFunctionTemplateDecl()) 817c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko return false; 818c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko if (const FunctionDecl *FD = 819c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko dyn_cast<FunctionDecl>(ThisDeclInfo->CurrentDecl)) 820c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko return FD->isVariadic(); 821651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (const FunctionTemplateDecl *FTD = 822651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines dyn_cast<FunctionTemplateDecl>(ThisDeclInfo->CurrentDecl)) 823651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return FTD->getTemplatedDecl()->isVariadic(); 824c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko if (const ObjCMethodDecl *MD = 825c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko dyn_cast<ObjCMethodDecl>(ThisDeclInfo->CurrentDecl)) 826c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko return MD->isVariadic(); 827c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko return false; 828c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko} 829c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko 83099a7057098c56211e641705e1ff38d4b7c8b309dFariborz Jahanianbool Sema::isObjCMethodDecl() { 83199a7057098c56211e641705e1ff38d4b7c8b309dFariborz Jahanian return isFunctionDecl() && ThisDeclInfo->CurrentDecl && 83299a7057098c56211e641705e1ff38d4b7c8b309dFariborz Jahanian isa<ObjCMethodDecl>(ThisDeclInfo->CurrentDecl); 83399a7057098c56211e641705e1ff38d4b7c8b309dFariborz Jahanian} 834a558d2e29817e36798875c96efb62251e53ff024Dmitri Gribenko 83599a7057098c56211e641705e1ff38d4b7c8b309dFariborz Jahanianbool Sema::isFunctionPointerVarDecl() { 836bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian if (!ThisDeclInfo) 837bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian return false; 838bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian if (!ThisDeclInfo->IsFilled) 839bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian inspectThisDecl(); 840bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian if (ThisDeclInfo->getKind() == DeclInfo::VariableKind) { 841bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian if (const VarDecl *VD = dyn_cast_or_null<VarDecl>(ThisDeclInfo->CurrentDecl)) { 842bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian QualType QT = VD->getType(); 843bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian return QT->isFunctionPointerType(); 844bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian } 845bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian } 846bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian return false; 847bca9788dbaf5fcf241efdc82ddcda712cb22214eFariborz Jahanian} 848651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 849664e860beb2550bef24fb8946192f61648a71d7fFariborz Jahanianbool Sema::isObjCPropertyDecl() { 850664e860beb2550bef24fb8946192f61648a71d7fFariborz Jahanian if (!ThisDeclInfo) 851664e860beb2550bef24fb8946192f61648a71d7fFariborz Jahanian return false; 852664e860beb2550bef24fb8946192f61648a71d7fFariborz Jahanian if (!ThisDeclInfo->IsFilled) 853664e860beb2550bef24fb8946192f61648a71d7fFariborz Jahanian inspectThisDecl(); 854664e860beb2550bef24fb8946192f61648a71d7fFariborz Jahanian return ThisDeclInfo->CurrentDecl->getKind() == Decl::ObjCProperty; 855664e860beb2550bef24fb8946192f61648a71d7fFariborz Jahanian} 8568487c524fdfcea3da858fd0af850b4784c8096d0Dmitri Gribenko 85704bf29eb1b197e0a103139ab5d63b0b97432f004Dmitri Gribenkobool Sema::isTemplateOrSpecialization() { 8581ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko if (!ThisDeclInfo) 8591ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko return false; 8601ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko if (!ThisDeclInfo->IsFilled) 86196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko inspectThisDecl(); 86204bf29eb1b197e0a103139ab5d63b0b97432f004Dmitri Gribenko return ThisDeclInfo->getTemplateKind() != DeclInfo::NotTemplate; 86396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko} 86496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 865b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanianbool Sema::isRecordLikeDecl() { 86628c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (!ThisDeclInfo) 86728c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return false; 86828c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (!ThisDeclInfo->IsFilled) 86928c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian inspectThisDecl(); 870651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return isUnionDecl() || isClassOrStructDecl() || isObjCInterfaceDecl() || 871651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines isObjCProtocolDecl(); 87228c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian} 87328c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian 87428c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanianbool Sema::isUnionDecl() { 87528c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (!ThisDeclInfo) 87628c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return false; 87728c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (!ThisDeclInfo->IsFilled) 87828c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian inspectThisDecl(); 87928c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (const RecordDecl *RD = 88028c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian dyn_cast_or_null<RecordDecl>(ThisDeclInfo->CurrentDecl)) 88128c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return RD->isUnion(); 88228c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return false; 88328c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian} 884651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 885b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanianbool Sema::isClassOrStructDecl() { 88628c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (!ThisDeclInfo) 88728c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return false; 88828c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (!ThisDeclInfo->IsFilled) 88928c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian inspectThisDecl(); 89028c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return ThisDeclInfo->CurrentDecl && 89128c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian isa<RecordDecl>(ThisDeclInfo->CurrentDecl) && 89228c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian !isUnionDecl(); 89328c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian} 894651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 8952d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanianbool Sema::isClassTemplateDecl() { 8962d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian if (!ThisDeclInfo) 8972d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian return false; 8982d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian if (!ThisDeclInfo->IsFilled) 8992d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian inspectThisDecl(); 9002d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian return ThisDeclInfo->CurrentDecl && 9012d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian (isa<ClassTemplateDecl>(ThisDeclInfo->CurrentDecl)); 9022d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian} 9032d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian 9042d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanianbool Sema::isFunctionTemplateDecl() { 9052d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian if (!ThisDeclInfo) 9062d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian return false; 9072d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian if (!ThisDeclInfo->IsFilled) 9082d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian inspectThisDecl(); 9092d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian return ThisDeclInfo->CurrentDecl && 910651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines (isa<FunctionTemplateDecl>(ThisDeclInfo->CurrentDecl)); 9112d588b4bc7127adf1a1c621002dfe452a99fef6fFariborz Jahanian} 91228c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian 91328c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanianbool Sema::isObjCInterfaceDecl() { 91428c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (!ThisDeclInfo) 91528c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return false; 91628c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (!ThisDeclInfo->IsFilled) 91728c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian inspectThisDecl(); 91828c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return ThisDeclInfo->CurrentDecl && 91928c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian isa<ObjCInterfaceDecl>(ThisDeclInfo->CurrentDecl); 92028c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian} 921651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 92228c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanianbool Sema::isObjCProtocolDecl() { 92328c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (!ThisDeclInfo) 92428c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return false; 92528c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian if (!ThisDeclInfo->IsFilled) 92628c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian inspectThisDecl(); 92728c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian return ThisDeclInfo->CurrentDecl && 92828c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian isa<ObjCProtocolDecl>(ThisDeclInfo->CurrentDecl); 92928c1cd2138f700742235e1e720c1f7e6dc75a11aFariborz Jahanian} 930651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 9318487c524fdfcea3da858fd0af850b4784c8096d0Dmitri GribenkoArrayRef<const ParmVarDecl *> Sema::getParamVars() { 9321ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko if (!ThisDeclInfo->IsFilled) 93300c59f7ed2814f67d6d7e844479ea99eca9e55efDmitri Gribenko inspectThisDecl(); 9341ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko return ThisDeclInfo->ParamVars; 9358487c524fdfcea3da858fd0af850b4784c8096d0Dmitri Gribenko} 9368487c524fdfcea3da858fd0af850b4784c8096d0Dmitri Gribenko 9378487c524fdfcea3da858fd0af850b4784c8096d0Dmitri Gribenkovoid Sema::inspectThisDecl() { 9381ca7ecc8854ffea215c033a0d8482551bf1b73f0Dmitri Gribenko ThisDeclInfo->fill(); 9398487c524fdfcea3da858fd0af850b4784c8096d0Dmitri Gribenko} 9408487c524fdfcea3da858fd0af850b4784c8096d0Dmitri Gribenko 941a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenkounsigned Sema::resolveParmVarReference(StringRef Name, 9428487c524fdfcea3da858fd0af850b4784c8096d0Dmitri Gribenko ArrayRef<const ParmVarDecl *> ParamVars) { 9438487c524fdfcea3da858fd0af850b4784c8096d0Dmitri Gribenko for (unsigned i = 0, e = ParamVars.size(); i != e; ++i) { 944a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko const IdentifierInfo *II = ParamVars[i]->getIdentifier(); 945a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko if (II && II->getName() == Name) 946a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko return i; 947a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 948c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko if (Name == "..." && isFunctionOrMethodVariadic()) 949c5b0054693b3b3cafe6a13549358c22e07fcd4ffDmitri Gribenko return ParamCommandComment::VarArgParamIndex; 950a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko return ParamCommandComment::InvalidParamIndex; 951a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko} 952a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 95396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkonamespace { 95496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkoclass SimpleTypoCorrector { 95596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko StringRef Typo; 95696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const unsigned MaxEditDistance; 95796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 95896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const NamedDecl *BestDecl; 95996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko unsigned BestEditDistance; 96096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko unsigned BestIndex; 96196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko unsigned NextIndex; 96296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 96396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkopublic: 96496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko SimpleTypoCorrector(StringRef Typo) : 96596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Typo(Typo), MaxEditDistance((Typo.size() + 2) / 3), 9666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BestDecl(nullptr), BestEditDistance(MaxEditDistance + 1), 96796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko BestIndex(0), NextIndex(0) 96896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko { } 96996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 97096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko void addDecl(const NamedDecl *ND); 97196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 97296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const NamedDecl *getBestDecl() const { 97396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (BestEditDistance > MaxEditDistance) 9746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 97596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 97696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return BestDecl; 97796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko } 97896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 97996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko unsigned getBestDeclIndex() const { 98096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko assert(getBestDecl()); 98196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return BestIndex; 98296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko } 98396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko}; 98496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 98596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkovoid SimpleTypoCorrector::addDecl(const NamedDecl *ND) { 98696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko unsigned CurrIndex = NextIndex++; 98796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 98896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const IdentifierInfo *II = ND->getIdentifier(); 98996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (!II) 99096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return; 99196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 99296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko StringRef Name = II->getName(); 99396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko unsigned MinPossibleEditDistance = abs((int)Name.size() - (int)Typo.size()); 99496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (MinPossibleEditDistance > 0 && 99596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Typo.size() / MinPossibleEditDistance < 3) 99696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return; 99796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 99896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko unsigned EditDistance = Typo.edit_distance(Name, true, MaxEditDistance); 99996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (EditDistance < BestEditDistance) { 100096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko BestEditDistance = EditDistance; 100196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko BestDecl = ND; 100296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko BestIndex = CurrIndex; 100396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko } 100496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko} 100596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko} // unnamed namespace 100696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 1007a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenkounsigned Sema::correctTypoInParmVarReference( 1008a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko StringRef Typo, 10098487c524fdfcea3da858fd0af850b4784c8096d0Dmitri Gribenko ArrayRef<const ParmVarDecl *> ParamVars) { 101096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko SimpleTypoCorrector Corrector(Typo); 101196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko for (unsigned i = 0, e = ParamVars.size(); i != e; ++i) 101296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Corrector.addDecl(ParamVars[i]); 101396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (Corrector.getBestDecl()) 101496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return Corrector.getBestDeclIndex(); 101596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko else 10161ad23d62007162df82b58bca31b4aa277a5f6586Dmitri Gribenko return ParamCommandComment::InvalidParamIndex; 101796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko} 101896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 101996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkonamespace { 102096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkobool ResolveTParamReferenceHelper( 102196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko StringRef Name, 102296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const TemplateParameterList *TemplateParameters, 102396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko SmallVectorImpl<unsigned> *Position) { 102496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko for (unsigned i = 0, e = TemplateParameters->size(); i != e; ++i) { 102596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const NamedDecl *Param = TemplateParameters->getParam(i); 102696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const IdentifierInfo *II = Param->getIdentifier(); 102796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (II && II->getName() == Name) { 102896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Position->push_back(i); 102996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return true; 103096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko } 103196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 103296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (const TemplateTemplateParmDecl *TTP = 103396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko dyn_cast<TemplateTemplateParmDecl>(Param)) { 103496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Position->push_back(i); 103596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (ResolveTParamReferenceHelper(Name, TTP->getTemplateParameters(), 103696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Position)) 103796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return true; 103896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Position->pop_back(); 1039a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 1040a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 104196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return false; 104296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko} 104396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko} // unnamed namespace 1044a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 104596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkobool Sema::resolveTParamReference( 104696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko StringRef Name, 104796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const TemplateParameterList *TemplateParameters, 104896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko SmallVectorImpl<unsigned> *Position) { 104996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Position->clear(); 105096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (!TemplateParameters) 105196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return false; 105296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 105396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return ResolveTParamReferenceHelper(Name, TemplateParameters, Position); 105496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko} 105596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 105696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkonamespace { 105796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenkovoid CorrectTypoInTParamReferenceHelper( 105896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const TemplateParameterList *TemplateParameters, 105996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko SimpleTypoCorrector &Corrector) { 106096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko for (unsigned i = 0, e = TemplateParameters->size(); i != e; ++i) { 106196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const NamedDecl *Param = TemplateParameters->getParam(i); 106296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Corrector.addDecl(Param); 106396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 106496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (const TemplateTemplateParmDecl *TTP = 106596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko dyn_cast<TemplateTemplateParmDecl>(Param)) 106696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko CorrectTypoInTParamReferenceHelper(TTP->getTemplateParameters(), 106796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko Corrector); 106896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko } 106996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko} 107096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko} // unnamed namespace 107196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko 107296b098674908eaa59a9128f3305cda6fbbdad563Dmitri GribenkoStringRef Sema::correctTypoInTParamReference( 107396b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko StringRef Typo, 107496b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const TemplateParameterList *TemplateParameters) { 107596b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko SimpleTypoCorrector Corrector(Typo); 107696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko CorrectTypoInTParamReferenceHelper(TemplateParameters, Corrector); 107796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko if (const NamedDecl *ND = Corrector.getBestDecl()) { 107896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko const IdentifierInfo *II = ND->getIdentifier(); 107996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko assert(II && "SimpleTypoCorrector should not return this decl"); 108096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return II->getName(); 108196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko } 108296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko return StringRef(); 1083a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko} 1084a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 10852d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri GribenkoInlineCommandComment::RenderKind 10862d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri GribenkoSema::getInlineCommandRenderKind(StringRef Name) const { 1087e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko assert(Traits.getCommandInfo(Name)->IsInlineCommand); 10882d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko 10892d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko return llvm::StringSwitch<InlineCommandComment::RenderKind>(Name) 10902d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko .Case("b", InlineCommandComment::RenderBold) 10912d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko .Cases("c", "p", InlineCommandComment::RenderMonospaced) 10922d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko .Cases("a", "e", "em", InlineCommandComment::RenderEmphasized) 10932d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko .Default(InlineCommandComment::RenderNormal); 10942d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko} 10952d66a5016d4aacce362f89290261c8a1a6eef0d3Dmitri Gribenko 10968d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} // end namespace comments 10978d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko} // end namespace clang 10988d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko 1099