doc parsing. Add @method and @callback for
checkings and few other refactoring/cleanup.
// rdar://13094352.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176509 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/CommentSema.cpp b/lib/AST/CommentSema.cpp
index 0cf7b5f..8adaa95 100644
--- a/lib/AST/CommentSema.cpp
+++ b/lib/AST/CommentSema.cpp
@@ -1,4 +1,4 @@
-//===--- CommentSema.cpp - Doxygen comment semantic analysis --------------===//
+class//===--- CommentSema.cpp - Doxygen comment semantic analysis --------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -91,9 +91,11 @@
 void Sema::checkFunctionDeclVerbatimLine(const BlockCommandComment *Comment) {
   const CommandInfo *Info = Traits.getCommandInfo(Comment->getCommandID());
   if (Info->IsFunctionDeclarationCommand &&
-      !isFunctionDecl())
+      !isFunctionDecl() && !isCallbackDecl())
     Diag(Comment->getLocation(),
          diag::warn_doc_function_not_attached_to_a_function_decl)
+    << Comment->getCommandMarker()
+    << Info->Name << Info->Name
     << Comment->getSourceRange();
 }
 
@@ -346,12 +348,14 @@
                                              unsigned CommandID,
                                              SourceLocation TextBegin,
                                              StringRef Text) {
-  return new (Allocator) VerbatimLineComment(
+  VerbatimLineComment *VL = new (Allocator) VerbatimLineComment(
                               LocBegin,
                               TextBegin.getLocWithOffset(Text.size()),
                               CommandID,
                               TextBegin,
                               Text);
+  checkFunctionDeclVerbatimLine(VL);
+  return VL;
 }
 
 HTMLStartTagComment *Sema::actOnHTMLStartTagStart(SourceLocation LocBegin,
@@ -682,6 +686,20 @@
   return ThisDeclInfo->getKind() == DeclInfo::FunctionKind;
 }
   
+bool Sema::isCallbackDecl() {
+  if (!ThisDeclInfo)
+    return false;
+  if (!ThisDeclInfo->IsFilled)
+    inspectThisDecl();
+  if (ThisDeclInfo->getKind() == DeclInfo::VariableKind) {
+    if (const VarDecl *VD = dyn_cast_or_null<VarDecl>(ThisDeclInfo->CurrentDecl)) {
+      QualType QT = VD->getType();
+      return QT->isFunctionPointerType();
+    }
+  }
+  return false;
+}
+  
 bool Sema::isObjCPropertyDecl() {
   if (!ThisDeclInfo)
     return false;