aaronpuchert created this revision.
aaronpuchert added a reviewer: gribozavr2.
aaronpuchert requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

We make all predicates expect an already inspected DeclInfo, and
introduce a function to run such a predicate after inspecting it.
Checks that were only used once have been inlined.

Before every call to inspectThisDecl the caller was checking IsFilled,
so we move that into the function itself.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D113795

Files:
  clang/include/clang/AST/CommentSema.h
  clang/lib/AST/CommentSema.cpp

Index: clang/lib/AST/CommentSema.cpp
===================================================================
--- clang/lib/AST/CommentSema.cpp
+++ clang/lib/AST/CommentSema.cpp
@@ -86,6 +86,12 @@
   }
 }
 
+/// \returns \c true if the declaration that this comment is attached to
+/// is a pointer to function/method/block type or has such a type.
+static bool involvesFunctionType(const DeclInfo &Info) {
+  return Info.involvesFunctionType();
+}
+
 ParamCommandComment *Sema::actOnParamCommandStart(
                                       SourceLocation LocBegin,
                                       SourceLocation LocEnd,
@@ -95,7 +101,7 @@
       new (Allocator) ParamCommandComment(LocBegin, LocEnd, CommandID,
                                           CommandMarker);
 
-  if (!involvesFunctionType())
+  if (!checkDecl(involvesFunctionType))
     Diag(Command->getLocation(),
          diag::warn_doc_param_not_attached_to_a_function_decl)
       << CommandMarker
@@ -105,23 +111,30 @@
 }
 
 void Sema::checkFunctionDeclVerbatimLine(const BlockCommandComment *Comment) {
+  if (ThisDeclInfo)
+    inspectThisDecl();
   unsigned DiagSelect;
   switch (Comment->getCommandID()) {
   case CommandTraits::KCI_function:
   case CommandTraits::KCI_functiongroup:
-    if (isAnyFunctionDecl() || isFunctionTemplateDecl())
+    if (ThisDeclInfo && ThisDeclInfo->getKind() == DeclInfo::FunctionKind &&
+        (isa<FunctionDecl>(ThisDeclInfo->CurrentDecl) ||
+         isa<FunctionTemplateDecl>(ThisDeclInfo->CurrentDecl)))
       return;
     DiagSelect = 0;
     break;
   case CommandTraits::KCI_method:
   case CommandTraits::KCI_methodgroup:
-    if (isObjCMethodDecl())
+    if (ThisDeclInfo && ThisDeclInfo->getKind() == DeclInfo::FunctionKind &&
+        isa<ObjCMethodDecl>(ThisDeclInfo->CurrentDecl))
       return;
     DiagSelect = 1;
     break;
   case CommandTraits::KCI_callback:
-    if (isFunctionPointerVarDecl())
-      return;
+    if (ThisDeclInfo && ThisDeclInfo->getKind() == DeclInfo::VariableKind)
+      if (const auto *VD = dyn_cast<VarDecl>(ThisDeclInfo->CurrentDecl))
+        if (VD->getType()->isFunctionPointerType())
+          return;
     DiagSelect = 2;
     break;
   default:
@@ -133,35 +146,80 @@
       << Comment->getSourceRange();
 }
 
+static bool isClassOrStructDeclImpl(const Decl *D) {
+  if (auto *record = dyn_cast_or_null<RecordDecl>(D))
+    return !record->isUnion();
+
+  return false;
+}
+
+/// \return \c true if the declaration that this comment is attached to
+/// declares either struct, class or tag typedef.
+static bool isClassOrStructOrTagTypedefDecl(const DeclInfo &Info) {
+  if (!Info.CurrentDecl)
+    return false;
+
+  if (isClassOrStructDeclImpl(Info.CurrentDecl))
+    return true;
+
+  if (auto *ThisTypedefDecl = dyn_cast<TypedefDecl>(Info.CurrentDecl)) {
+    auto UnderlyingType = ThisTypedefDecl->getUnderlyingType();
+    if (auto ThisElaboratedType = dyn_cast<ElaboratedType>(UnderlyingType)) {
+      auto DesugaredType = ThisElaboratedType->desugar();
+      if (auto *DesugaredTypePtr = DesugaredType.getTypePtrOrNull()) {
+        if (auto *ThisRecordType = dyn_cast<RecordType>(DesugaredTypePtr)) {
+          return isClassOrStructDeclImpl(ThisRecordType->getAsRecordDecl());
+        }
+      }
+    }
+  }
+
+  return false;
+}
+
+static bool isObjCInterfaceDecl(const DeclInfo &Info) {
+  return isa_and_nonnull<ObjCInterfaceDecl>(Info.CurrentDecl);
+}
+
+static bool isObjCProtocolDecl(const DeclInfo &Info) {
+  return isa_and_nonnull<ObjCProtocolDecl>(Info.CurrentDecl);
+}
+
 void Sema::checkContainerDeclVerbatimLine(const BlockCommandComment *Comment) {
-  switch (Comment->getCommandID()) {
+  if (ThisDeclInfo) {
+    inspectThisDecl();
+    switch (Comment->getCommandID()) {
     case CommandTraits::KCI_class:
-      if (isClassOrStructOrTagTypedefDecl() || isClassTemplateDecl())
+      if (isClassOrStructOrTagTypedefDecl(*ThisDeclInfo) ||
+          isa_and_nonnull<ClassTemplateDecl>(ThisDeclInfo->CurrentDecl))
         return;
       // Allow @class command on @interface declarations.
       // FIXME. Currently, \class and @class are indistinguishable. So,
       // \class is also allowed on an @interface declaration
-      if (Comment->getCommandMarker() && isObjCInterfaceDecl())
+      if (Comment->getCommandMarker() && isObjCInterfaceDecl(*ThisDeclInfo))
         return;
       break;
     case CommandTraits::KCI_interface:
-      if (isObjCInterfaceDecl())
+      if (isObjCInterfaceDecl(*ThisDeclInfo))
         return;
       break;
     case CommandTraits::KCI_protocol:
-      if (isObjCProtocolDecl())
+      if (isObjCProtocolDecl(*ThisDeclInfo))
         return;
       break;
     case CommandTraits::KCI_struct:
-      if (isClassOrStructOrTagTypedefDecl())
+      if (isClassOrStructOrTagTypedefDecl(*ThisDeclInfo))
         return;
       break;
     case CommandTraits::KCI_union:
-      if (isUnionDecl())
-        return;
+      if (const RecordDecl *RD =
+              dyn_cast_or_null<RecordDecl>(ThisDeclInfo->CurrentDecl))
+        if (RD->isUnion())
+          return;
       break;
     default:
       llvm_unreachable("Unhandled command with IsRecordLikeDeclarationCommand");
+    }
   }
   Diag(Comment->getLocation(), diag::warn_doc_api_container_decl_mismatch)
       << Comment->getCommandMarker()
@@ -169,8 +227,13 @@
       << Comment->getSourceRange();
 }
 
+static bool isRecordLikeDecl(const DeclInfo &Info) {
+  return isa_and_nonnull<RecordDecl>(Info.CurrentDecl) ||
+         isObjCInterfaceDecl(Info) || isObjCProtocolDecl(Info);
+}
+
 void Sema::checkContainerDecl(const BlockCommandComment *Comment) {
-  if (isRecordLikeDecl())
+  if (checkDecl(isRecordLikeDecl))
     return;
   Diag(Comment->getLocation(), diag::warn_doc_container_decl_mismatch)
       << Comment->getCommandMarker()
@@ -240,6 +303,10 @@
   checkBlockCommandEmptyParagraph(Command);
 }
 
+static bool isTemplateOrSpecialization(const DeclInfo &Info) {
+  return Info.getTemplateKind() != DeclInfo::NotTemplate;
+}
+
 TParamCommandComment *Sema::actOnTParamCommandStart(
                                       SourceLocation LocBegin,
                                       SourceLocation LocEnd,
@@ -249,7 +316,7 @@
       new (Allocator) TParamCommandComment(LocBegin, LocEnd, CommandID,
                                            CommandMarker);
 
-  if (!isTemplateOrSpecialization())
+  if (!checkDecl(isTemplateOrSpecialization))
     Diag(Command->getLocation(),
          diag::warn_doc_tparam_not_attached_to_a_template_decl)
       << CommandMarker
@@ -271,7 +338,7 @@
                                          Arg);
   Command->setArgs(llvm::makeArrayRef(A, 1));
 
-  if (!isTemplateOrSpecialization()) {
+  if (!checkDecl(isTemplateOrSpecialization)) {
     // We already warned that this \\tparam is not attached to a template decl.
     return;
   }
@@ -544,12 +611,13 @@
 
 void Sema::checkReturnsCommand(const BlockCommandComment *Command) {
   assert(ThisDeclInfo && "should not call this check on a bare comment");
+  inspectThisDecl();
 
   // We allow the return command for all @properties because it can be used
   // to document the value that the property getter returns.
-  if (isObjCPropertyDecl())
+  if (ThisDeclInfo->CurrentDecl->getKind() == Decl::ObjCProperty)
     return;
-  if (involvesFunctionType()) {
+  if (involvesFunctionType(*ThisDeclInfo)) {
     assert(!ThisDeclInfo->ReturnType.isNull() &&
            "should have a valid return type");
     if (ThisDeclInfo->ReturnType->isVoidType()) {
@@ -675,7 +743,7 @@
 }
 
 void Sema::resolveParamCommandIndexes(const FullComment *FC) {
-  if (!involvesFunctionType()) {
+  if (!checkDecl(involvesFunctionType)) {
     // We already warned that \\param commands are not attached to a function
     // decl.
     return;
@@ -763,179 +831,21 @@
   }
 }
 
-bool Sema::involvesFunctionType() {
-  if (!ThisDeclInfo)
-    return false;
-  if (!ThisDeclInfo->IsFilled)
-    inspectThisDecl();
-  return ThisDeclInfo->involvesFunctionType();
-}
-
-bool Sema::isFunctionDecl() {
-  if (!ThisDeclInfo)
-    return false;
-  if (!ThisDeclInfo->IsFilled)
-    inspectThisDecl();
-  return ThisDeclInfo->getKind() == DeclInfo::FunctionKind;
-}
-
-bool Sema::isAnyFunctionDecl() {
-  return isFunctionDecl() && ThisDeclInfo->CurrentDecl &&
-         isa<FunctionDecl>(ThisDeclInfo->CurrentDecl);
-}
-
-bool Sema::isFunctionOrMethodVariadic() {
-  if (!ThisDeclInfo)
-    return false;
-  if (!ThisDeclInfo->IsFilled)
-    inspectThisDecl();
-  return ThisDeclInfo->IsVariadic;
-}
-
-bool Sema::isObjCMethodDecl() {
-  return isFunctionDecl() && ThisDeclInfo->CurrentDecl &&
-         isa<ObjCMethodDecl>(ThisDeclInfo->CurrentDecl);
-}
-
-bool Sema::isFunctionPointerVarDecl() {
-  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() {
+bool Sema::checkDecl(bool (*check)(const DeclInfo &)) {
   if (!ThisDeclInfo)
     return false;
-  if (!ThisDeclInfo->IsFilled)
-    inspectThisDecl();
-  return ThisDeclInfo->CurrentDecl->getKind() == Decl::ObjCProperty;
-}
-
-bool Sema::isTemplateOrSpecialization() {
-  if (!ThisDeclInfo)
-    return false;
-  if (!ThisDeclInfo->IsFilled)
-    inspectThisDecl();
-  return ThisDeclInfo->getTemplateKind() != DeclInfo::NotTemplate;
-}
-
-bool Sema::isRecordLikeDecl() {
-  if (!ThisDeclInfo)
-    return false;
-  if (!ThisDeclInfo->IsFilled)
-    inspectThisDecl();
-  return isUnionDecl() || isClassOrStructDecl() || isObjCInterfaceDecl() ||
-         isObjCProtocolDecl();
-}
-
-bool Sema::isUnionDecl() {
-  if (!ThisDeclInfo)
-    return false;
-  if (!ThisDeclInfo->IsFilled)
-    inspectThisDecl();
-  if (const RecordDecl *RD =
-        dyn_cast_or_null<RecordDecl>(ThisDeclInfo->CurrentDecl))
-    return RD->isUnion();
-  return false;
-}
-static bool isClassOrStructDeclImpl(const Decl *D) {
-  if (auto *record = dyn_cast_or_null<RecordDecl>(D))
-    return !record->isUnion();
-
-  return false;
-}
-
-bool Sema::isClassOrStructDecl() {
-  if (!ThisDeclInfo)
-    return false;
-  if (!ThisDeclInfo->IsFilled)
-    inspectThisDecl();
-
-  if (!ThisDeclInfo->CurrentDecl)
-    return false;
-
-  return isClassOrStructDeclImpl(ThisDeclInfo->CurrentDecl);
-}
-
-bool Sema::isClassOrStructOrTagTypedefDecl() {
-  if (!ThisDeclInfo)
-    return false;
-  if (!ThisDeclInfo->IsFilled)
-    inspectThisDecl();
-
-  if (!ThisDeclInfo->CurrentDecl)
-    return false;
-
-  if (isClassOrStructDeclImpl(ThisDeclInfo->CurrentDecl))
-    return true;
-
-  if (auto *ThisTypedefDecl = dyn_cast<TypedefDecl>(ThisDeclInfo->CurrentDecl)) {
-    auto UnderlyingType = ThisTypedefDecl->getUnderlyingType();
-    if (auto ThisElaboratedType = dyn_cast<ElaboratedType>(UnderlyingType)) {
-      auto DesugaredType = ThisElaboratedType->desugar();
-      if (auto *DesugaredTypePtr = DesugaredType.getTypePtrOrNull()) {
-        if (auto *ThisRecordType = dyn_cast<RecordType>(DesugaredTypePtr)) {
-          return isClassOrStructDeclImpl(ThisRecordType->getAsRecordDecl());
-        }
-      }
-    }
-  }
-
-  return false;
-}
-
-bool Sema::isClassTemplateDecl() {
-  if (!ThisDeclInfo)
-    return false;
-  if (!ThisDeclInfo->IsFilled)
-    inspectThisDecl();
-  return ThisDeclInfo->CurrentDecl &&
-          (isa<ClassTemplateDecl>(ThisDeclInfo->CurrentDecl));
-}
-
-bool Sema::isFunctionTemplateDecl() {
-  if (!ThisDeclInfo)
-    return false;
-  if (!ThisDeclInfo->IsFilled)
-    inspectThisDecl();
-  return ThisDeclInfo->CurrentDecl &&
-         (isa<FunctionTemplateDecl>(ThisDeclInfo->CurrentDecl));
-}
-
-bool Sema::isObjCInterfaceDecl() {
-  if (!ThisDeclInfo)
-    return false;
-  if (!ThisDeclInfo->IsFilled)
-    inspectThisDecl();
-  return ThisDeclInfo->CurrentDecl &&
-         isa<ObjCInterfaceDecl>(ThisDeclInfo->CurrentDecl);
-}
-
-bool Sema::isObjCProtocolDecl() {
-  if (!ThisDeclInfo)
-    return false;
-  if (!ThisDeclInfo->IsFilled)
-    inspectThisDecl();
-  return ThisDeclInfo->CurrentDecl &&
-         isa<ObjCProtocolDecl>(ThisDeclInfo->CurrentDecl);
+  inspectThisDecl();
+  return check(*ThisDeclInfo);
 }
 
 ArrayRef<const ParmVarDecl *> Sema::getParamVars() {
-  if (!ThisDeclInfo->IsFilled)
-    inspectThisDecl();
+  inspectThisDecl();
   return ThisDeclInfo->ParamVars;
 }
 
 void Sema::inspectThisDecl() {
-  ThisDeclInfo->fill();
+  if (!ThisDeclInfo->IsFilled)
+    ThisDeclInfo->fill();
 }
 
 unsigned Sema::resolveParmVarReference(StringRef Name,
@@ -945,7 +855,7 @@
     if (II && II->getName() == Name)
       return i;
   }
-  if (Name == "..." && isFunctionOrMethodVariadic())
+  if (Name == "..." && ThisDeclInfo->IsVariadic)
     return ParamCommandComment::VarArgParamIndex;
   return ParamCommandComment::InvalidParamIndex;
 }
Index: clang/include/clang/AST/CommentSema.h
===================================================================
--- clang/include/clang/AST/CommentSema.h
+++ clang/include/clang/AST/CommentSema.h
@@ -202,30 +202,7 @@
   /// Emit diagnostics about unknown parametrs.
   void resolveParamCommandIndexes(const FullComment *FC);
 
-  /// \returns \c true if the declaration that this comment is attached to
-  /// is a pointer to function/method/block type or has such a type.
-  bool involvesFunctionType();
-
-  bool isFunctionDecl();
-  bool isAnyFunctionDecl();
-
-  /// \returns \c true if declaration that this comment is attached to declares
-  /// a function pointer.
-  bool isFunctionPointerVarDecl();
-  bool isFunctionOrMethodVariadic();
-  bool isObjCMethodDecl();
-  bool isObjCPropertyDecl();
-  bool isTemplateOrSpecialization();
-  bool isRecordLikeDecl();
-  bool isClassOrStructDecl();
-  /// \return \c true if the declaration that this comment is attached to
-  /// declares either struct, class or tag typedef.
-  bool isClassOrStructOrTagTypedefDecl();
-  bool isUnionDecl();
-  bool isObjCInterfaceDecl();
-  bool isObjCProtocolDecl();
-  bool isClassTemplateDecl();
-  bool isFunctionTemplateDecl();
+  bool checkDecl(bool (*check)(const DeclInfo &));
 
   ArrayRef<const ParmVarDecl *> getParamVars();
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to