diff options
author | dim <dim@FreeBSD.org> | 2014-11-24 09:15:30 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2014-11-24 09:15:30 +0000 |
commit | 173a4f43a911175643bda81ee675e8d9269056ea (patch) | |
tree | 47df2c12b57214af6c31e47404b005675b8b7ffc /lib/AST/CommentSema.cpp | |
parent | 88f7a7d5251a2d813460274c92decc143a11569b (diff) | |
download | FreeBSD-src-173a4f43a911175643bda81ee675e8d9269056ea.zip FreeBSD-src-173a4f43a911175643bda81ee675e8d9269056ea.tar.gz |
Vendor import of clang RELEASE_350/final tag r216957 (effectively, 3.5.0 release):
https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_350/final@216957
Diffstat (limited to 'lib/AST/CommentSema.cpp')
-rw-r--r-- | lib/AST/CommentSema.cpp | 79 |
1 files changed, 56 insertions, 23 deletions
diff --git a/lib/AST/CommentSema.cpp b/lib/AST/CommentSema.cpp index 1c6222f..12823c3 100644 --- a/lib/AST/CommentSema.cpp +++ b/lib/AST/CommentSema.cpp @@ -29,7 +29,8 @@ Sema::Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr, DiagnosticsEngine &Diags, CommandTraits &Traits, const Preprocessor *PP) : Allocator(Allocator), SourceMgr(SourceMgr), Diags(Diags), Traits(Traits), - PP(PP), ThisDeclInfo(NULL), BriefCommand(NULL), HeaderfileCommand(NULL) { + PP(PP), ThisDeclInfo(nullptr), BriefCommand(nullptr), + HeaderfileCommand(nullptr) { } void Sema::setDecl(const Decl *D) { @@ -68,8 +69,12 @@ void Sema::actOnBlockCommandFinish(BlockCommandComment *Command, Command->setParagraph(Paragraph); checkBlockCommandEmptyParagraph(Command); checkBlockCommandDuplicate(Command); - checkReturnsCommand(Command); - checkDeprecatedCommand(Command); + if (ThisDeclInfo) { + // These checks only make sense if the comment is attached to a + // declaration. + checkReturnsCommand(Command); + checkDeprecatedCommand(Command); + } } ParamCommandComment *Sema::actOnParamCommandStart( @@ -122,7 +127,7 @@ void Sema::checkFunctionDeclVerbatimLine(const BlockCommandComment *Comment) { << (DiagSelect-1) << (DiagSelect-1) << Comment->getSourceRange(); } - + void Sema::checkContainerDeclVerbatimLine(const BlockCommandComment *Comment) { const CommandInfo *Info = Traits.getCommandInfo(Comment->getCommandID()); if (!Info->IsRecordLikeDeclarationCommand) @@ -478,6 +483,7 @@ HTMLEndTagComment *Sema::actOnHTMLEndTag(SourceLocation LocBegin, if (isHTMLEndTagForbidden(TagName)) { Diag(HET->getLocation(), diag::warn_doc_html_end_forbidden) << TagName << HET->getSourceRange(); + HET->setIsMalformed(); return HET; } @@ -493,14 +499,19 @@ HTMLEndTagComment *Sema::actOnHTMLEndTag(SourceLocation LocBegin, if (!FoundOpen) { Diag(HET->getLocation(), diag::warn_doc_html_end_unbalanced) << HET->getSourceRange(); + HET->setIsMalformed(); return HET; } while (!HTMLOpenTags.empty()) { - const HTMLStartTagComment *HST = HTMLOpenTags.pop_back_val(); + HTMLStartTagComment *HST = HTMLOpenTags.pop_back_val(); StringRef LastNotClosedTagName = HST->getTagName(); - if (LastNotClosedTagName == TagName) + if (LastNotClosedTagName == TagName) { + // If the start tag is malformed, end tag is malformed as well. + if (HST->isMalformed()) + HET->setIsMalformed(); break; + } if (isHTMLEndTagOptional(LastNotClosedTagName)) continue; @@ -514,16 +525,18 @@ HTMLEndTagComment *Sema::actOnHTMLEndTag(SourceLocation LocBegin, HET->getLocation(), &CloseLineInvalid); - if (OpenLineInvalid || CloseLineInvalid || OpenLine == CloseLine) + if (OpenLineInvalid || CloseLineInvalid || OpenLine == CloseLine) { Diag(HST->getLocation(), diag::warn_doc_html_start_end_mismatch) << HST->getTagName() << HET->getTagName() << HST->getSourceRange() << HET->getSourceRange(); - else { + HST->setIsMalformed(); + } else { Diag(HST->getLocation(), diag::warn_doc_html_start_end_mismatch) << HST->getTagName() << HET->getTagName() << HST->getSourceRange(); Diag(HET->getLocation(), diag::note_doc_html_end_tag) << HET->getSourceRange(); + HST->setIsMalformed(); } } @@ -534,6 +547,18 @@ FullComment *Sema::actOnFullComment( ArrayRef<BlockContentComment *> Blocks) { FullComment *FC = new (Allocator) FullComment(Blocks, ThisDeclInfo); resolveParamCommandIndexes(FC); + + // Complain about HTML tags that are not closed. + while (!HTMLOpenTags.empty()) { + HTMLStartTagComment *HST = HTMLOpenTags.pop_back_val(); + if (isHTMLEndTagOptional(HST->getTagName())) + continue; + + Diag(HST->getLocation(), diag::warn_doc_html_missing_end_tag) + << HST->getTagName() << HST->getSourceRange(); + HST->setIsMalformed(); + } + return FC; } @@ -558,8 +583,11 @@ void Sema::checkBlockCommandEmptyParagraph(BlockCommandComment *Command) { void Sema::checkReturnsCommand(const BlockCommandComment *Command) { if (!Traits.getCommandInfo(Command->getCommandID())->IsReturnsCommand) return; + + assert(ThisDeclInfo && "should not call this check on a bare comment"); + if (isFunctionDecl()) { - if (ThisDeclInfo->ResultType->isVoidType()) { + if (ThisDeclInfo->ReturnType->isVoidType()) { unsigned DiagKind; switch (ThisDeclInfo->CommentDecl->getKind()) { default: @@ -586,7 +614,7 @@ void Sema::checkReturnsCommand(const BlockCommandComment *Command) { } else if (isObjCPropertyDecl()) return; - + Diag(Command->getLocation(), diag::warn_doc_returns_not_attached_to_a_function_decl) << Command->getCommandMarker() @@ -596,7 +624,7 @@ void Sema::checkReturnsCommand(const BlockCommandComment *Command) { void Sema::checkBlockCommandDuplicate(const BlockCommandComment *Command) { const CommandInfo *Info = Traits.getCommandInfo(Command->getCommandID()); - const BlockCommandComment *PrevCommand = NULL; + const BlockCommandComment *PrevCommand = nullptr; if (Info->IsBriefCommand) { if (!BriefCommand) { BriefCommand = Command; @@ -636,6 +664,8 @@ void Sema::checkDeprecatedCommand(const BlockCommandComment *Command) { if (!Traits.getCommandInfo(Command->getCommandID())->IsDeprecatedCommand) return; + assert(ThisDeclInfo && "should not call this check on a bare comment"); + const Decl *D = ThisDeclInfo->CommentDecl; if (!D) return; @@ -694,7 +724,7 @@ void Sema::resolveParamCommandIndexes(const FullComment *FC) { SmallVector<ParamCommandComment *, 8> ParamVarDocs; ArrayRef<const ParmVarDecl *> ParamVars = getParamVars(); - ParamVarDocs.resize(ParamVars.size(), NULL); + ParamVarDocs.resize(ParamVars.size(), nullptr); // First pass over all \\param commands: resolve all parameter names. for (Comment::child_iterator I = FC->child_begin(), E = FC->child_end(); @@ -783,11 +813,14 @@ bool Sema::isAnyFunctionDecl() { } bool Sema::isFunctionOrMethodVariadic() { - if (!isAnyFunctionDecl() && !isObjCMethodDecl()) + if (!isAnyFunctionDecl() && !isObjCMethodDecl() && !isFunctionTemplateDecl()) return false; if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ThisDeclInfo->CurrentDecl)) return FD->isVariadic(); + if (const FunctionTemplateDecl *FTD = + dyn_cast<FunctionTemplateDecl>(ThisDeclInfo->CurrentDecl)) + return FTD->getTemplatedDecl()->isVariadic(); if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(ThisDeclInfo->CurrentDecl)) return MD->isVariadic(); @@ -812,7 +845,7 @@ bool Sema::isFunctionPointerVarDecl() { } return false; } - + bool Sema::isObjCPropertyDecl() { if (!ThisDeclInfo) return false; @@ -834,8 +867,8 @@ bool Sema::isRecordLikeDecl() { return false; if (!ThisDeclInfo->IsFilled) inspectThisDecl(); - return isUnionDecl() || isClassOrStructDecl() - || isObjCInterfaceDecl() || isObjCProtocolDecl(); + return isUnionDecl() || isClassOrStructDecl() || isObjCInterfaceDecl() || + isObjCProtocolDecl(); } bool Sema::isUnionDecl() { @@ -848,7 +881,7 @@ bool Sema::isUnionDecl() { return RD->isUnion(); return false; } - + bool Sema::isClassOrStructDecl() { if (!ThisDeclInfo) return false; @@ -858,7 +891,7 @@ bool Sema::isClassOrStructDecl() { isa<RecordDecl>(ThisDeclInfo->CurrentDecl) && !isUnionDecl(); } - + bool Sema::isClassTemplateDecl() { if (!ThisDeclInfo) return false; @@ -874,7 +907,7 @@ bool Sema::isFunctionTemplateDecl() { if (!ThisDeclInfo->IsFilled) inspectThisDecl(); return ThisDeclInfo->CurrentDecl && - (isa<FunctionTemplateDecl>(ThisDeclInfo->CurrentDecl)); + (isa<FunctionTemplateDecl>(ThisDeclInfo->CurrentDecl)); } bool Sema::isObjCInterfaceDecl() { @@ -885,7 +918,7 @@ bool Sema::isObjCInterfaceDecl() { return ThisDeclInfo->CurrentDecl && isa<ObjCInterfaceDecl>(ThisDeclInfo->CurrentDecl); } - + bool Sema::isObjCProtocolDecl() { if (!ThisDeclInfo) return false; @@ -894,7 +927,7 @@ bool Sema::isObjCProtocolDecl() { return ThisDeclInfo->CurrentDecl && isa<ObjCProtocolDecl>(ThisDeclInfo->CurrentDecl); } - + ArrayRef<const ParmVarDecl *> Sema::getParamVars() { if (!ThisDeclInfo->IsFilled) inspectThisDecl(); @@ -930,7 +963,7 @@ class SimpleTypoCorrector { public: SimpleTypoCorrector(StringRef Typo) : Typo(Typo), MaxEditDistance((Typo.size() + 2) / 3), - BestDecl(NULL), BestEditDistance(MaxEditDistance + 1), + BestDecl(nullptr), BestEditDistance(MaxEditDistance + 1), BestIndex(0), NextIndex(0) { } @@ -938,7 +971,7 @@ public: const NamedDecl *getBestDecl() const { if (BestEditDistance > MaxEditDistance) - return NULL; + return nullptr; return BestDecl; } |