[clang-tools-extra] 4df84ac - [clang-doc] Centralize TypeInfo creation.

Paul Kirth via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 20 10:56:21 PDT 2022


Author: Brett Wilson
Date: 2022-09-20T17:55:47Z
New Revision: 4df84ac377dfc88da0217dc8cbb9aa69be6cbe55

URL: https://github.com/llvm/llvm-project/commit/4df84ac377dfc88da0217dc8cbb9aa69be6cbe55
DIFF: https://github.com/llvm/llvm-project/commit/4df84ac377dfc88da0217dc8cbb9aa69be6cbe55.diff

LOG: [clang-doc] Centralize TypeInfo creation.

Several different places in the code had similar computations for the parameters that were eventually passed to the TypeInfo constructor.

This centralizes that code in one function, and allows passing TypeInfo to the various other *Info structures that need it.

Remove some "auto" types and replace with the real type for getting declarations. This was making some duplicate checking difficult to see.

Reviewed By: paulkirth

Differential Revision: https://reviews.llvm.org/D134225

Added: 
    

Modified: 
    clang-tools-extra/clang-doc/Representation.h
    clang-tools-extra/clang-doc/Serialize.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clang-doc/Representation.h b/clang-tools-extra/clang-doc/Representation.h
index 0f0a838148223..5385aa96c1f52 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -158,6 +158,8 @@ struct Reference {
 // A base struct for TypeInfos
 struct TypeInfo {
   TypeInfo() = default;
+  TypeInfo(const Reference &R) : Type(R) {}
+
   TypeInfo(SymbolID Type, StringRef Field, InfoType IT)
       : Type(Type, Field, IT) {}
   TypeInfo(SymbolID Type, StringRef Field, InfoType IT, StringRef Path)
@@ -173,6 +175,9 @@ struct TypeInfo {
 // Info for field types.
 struct FieldTypeInfo : public TypeInfo {
   FieldTypeInfo() = default;
+  FieldTypeInfo(const TypeInfo &TI, StringRef Name = StringRef(),
+                StringRef DefaultValue = StringRef())
+      : TypeInfo(TI), Name(Name), DefaultValue(DefaultValue) {}
   FieldTypeInfo(SymbolID Type, StringRef Field, InfoType IT, StringRef Path,
                 llvm::StringRef Name)
       : TypeInfo(Type, Field, IT, Path), Name(Name) {}
@@ -196,6 +201,8 @@ struct FieldTypeInfo : public TypeInfo {
 // Info for member types.
 struct MemberTypeInfo : public FieldTypeInfo {
   MemberTypeInfo() = default;
+  MemberTypeInfo(const TypeInfo &TI, StringRef Name, AccessSpecifier Access)
+      : FieldTypeInfo(TI, Name), Access(Access) {}
   MemberTypeInfo(SymbolID Type, StringRef Field, InfoType IT, StringRef Path,
                  llvm::StringRef Name, AccessSpecifier Access)
       : FieldTypeInfo(Type, Field, IT, Path, Name), Access(Access) {}

diff  --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp
index 4c161f0640c61..45056061a6407 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -224,12 +224,35 @@ static SymbolID getUSRForDecl(const Decl *D) {
   return hashUSR(USR);
 }
 
-static RecordDecl *getDeclForType(const QualType &T) {
+static TagDecl *getTagDeclForType(const QualType &T) {
+  if (const TagDecl *D = T->getAsTagDecl())
+    return D->getDefinition();
+  return nullptr;
+}
+
+static RecordDecl *getRecordDeclForType(const QualType &T) {
   if (const RecordDecl *D = T->getAsRecordDecl())
     return D->getDefinition();
   return nullptr;
 }
 
+TypeInfo getTypeInfoForType(const QualType &T) {
+  const TagDecl *TD = getTagDeclForType(T);
+  if (!TD)
+    return TypeInfo(Reference(T.getAsString()));
+
+  InfoType IT;
+  if (dyn_cast<EnumDecl>(TD)) {
+    IT = InfoType::IT_enum;
+  } else if (dyn_cast<RecordDecl>(TD)) {
+    IT = InfoType::IT_record;
+  } else {
+    IT = InfoType::IT_default;
+  }
+  return TypeInfo(Reference(getUSRForDecl(TD), TD->getNameAsString(), IT,
+                            getInfoRelativePath(TD)));
+}
+
 static bool isPublic(const clang::AccessSpecifier AS,
                      const clang::Linkage Link) {
   if (AS == clang::AccessSpecifier::AS_private)
@@ -286,28 +309,14 @@ static void parseFields(RecordInfo &I, const RecordDecl *D, bool PublicOnly,
   for (const FieldDecl *F : D->fields()) {
     if (!shouldSerializeInfo(PublicOnly, /*IsInAnonymousNamespace=*/false, F))
       continue;
-    if (const auto *T = getDeclForType(F->getTypeSourceInfo()->getType())) {
-      // Use getAccessUnsafe so that we just get the default AS_none if it's not
-      // valid, as opposed to an assert.
-      if (const auto *N = dyn_cast<EnumDecl>(T)) {
-        I.Members.emplace_back(
-            getUSRForDecl(T), N->getNameAsString(), InfoType::IT_enum,
-            getInfoRelativePath(N), F->getNameAsString(),
-            getFinalAccessSpecifier(Access, N->getAccessUnsafe()));
-        continue;
-      } else if (const auto *N = dyn_cast<RecordDecl>(T)) {
-        I.Members.emplace_back(
-            getUSRForDecl(T), N->getNameAsString(), InfoType::IT_record,
-            getInfoRelativePath(N), F->getNameAsString(),
-            getFinalAccessSpecifier(Access, N->getAccessUnsafe()));
-        continue;
-      }
-    }
 
-    auto& member = I.Members.emplace_back(
-        F->getTypeSourceInfo()->getType().getAsString(), F->getNameAsString(),
+    // Use getAccessUnsafe so that we just get the default AS_none if it's not
+    // valid, as opposed to an assert.
+    MemberTypeInfo &NewMember = I.Members.emplace_back(
+        getTypeInfoForType(F->getTypeSourceInfo()->getType()),
+        F->getNameAsString(),
         getFinalAccessSpecifier(Access, F->getAccessUnsafe()));
-    populateMemberTypeInfo(member, F);
+    populateMemberTypeInfo(NewMember, F);
   }
 }
 
@@ -325,27 +334,11 @@ static void parseEnumerators(EnumInfo &I, const EnumDecl *D) {
 
 static void parseParameters(FunctionInfo &I, const FunctionDecl *D) {
   for (const ParmVarDecl *P : D->parameters()) {
-    FieldTypeInfo *FieldInfo = nullptr;
-    if (const auto *T = getDeclForType(P->getOriginalType())) {
-      if (const auto *N = dyn_cast<EnumDecl>(T)) {
-        FieldInfo = &I.Params.emplace_back(
-            getUSRForDecl(N), N->getNameAsString(), InfoType::IT_enum,
-            getInfoRelativePath(N), P->getNameAsString());
-      } else if (const auto *N = dyn_cast<RecordDecl>(T)) {
-        FieldInfo = &I.Params.emplace_back(
-            getUSRForDecl(N), N->getNameAsString(), InfoType::IT_record,
-            getInfoRelativePath(N), P->getNameAsString());
-      }
-      // Otherwise fall through to the default case below.
-    }
-
-    if (!FieldInfo) {
-      FieldInfo = &I.Params.emplace_back(P->getOriginalType().getAsString(),
-                                         P->getNameAsString());
-    }
+    FieldTypeInfo &FieldInfo = I.Params.emplace_back(
+        getTypeInfoForType(P->getOriginalType()), P->getNameAsString());
 
     if (const Expr *DefaultArg = P->getDefaultArg()) {
-      FieldInfo->DefaultValue = getSourceCode(D, DefaultArg->getSourceRange());
+      FieldInfo.DefaultValue = getSourceCode(D, DefaultArg->getSourceRange());
     }
   }
 }
@@ -363,14 +356,14 @@ static void parseBases(RecordInfo &I, const CXXRecordDecl *D) {
       const TemplateDecl *D = Ty->getTemplateName().getAsTemplateDecl();
       I.Parents.emplace_back(getUSRForDecl(D), B.getType().getAsString(),
                              InfoType::IT_record);
-    } else if (const RecordDecl *P = getDeclForType(B.getType()))
+    } else if (const RecordDecl *P = getRecordDeclForType(B.getType()))
       I.Parents.emplace_back(getUSRForDecl(P), P->getNameAsString(),
                              InfoType::IT_record, getInfoRelativePath(P));
     else
       I.Parents.emplace_back(B.getType().getAsString());
   }
   for (const CXXBaseSpecifier &B : D->vbases()) {
-    if (const auto *P = getDeclForType(B.getType()))
+    if (const RecordDecl *P = getRecordDeclForType(B.getType()))
       I.VirtualParents.emplace_back(getUSRForDecl(P), P->getNameAsString(),
                                     InfoType::IT_record,
                                     getInfoRelativePath(P));
@@ -444,16 +437,7 @@ static void populateFunctionInfo(FunctionInfo &I, const FunctionDecl *D,
                                  bool &IsInAnonymousNamespace) {
   populateSymbolInfo(I, D, FC, LineNumber, Filename, IsFileInRootDir,
                      IsInAnonymousNamespace);
-  if (const auto *T = getDeclForType(D->getReturnType())) {
-    if (isa<EnumDecl>(T))
-      I.ReturnType = TypeInfo(getUSRForDecl(T), T->getNameAsString(),
-                              InfoType::IT_enum, getInfoRelativePath(T));
-    else if (isa<RecordDecl>(T))
-      I.ReturnType = TypeInfo(getUSRForDecl(T), T->getNameAsString(),
-                              InfoType::IT_record, getInfoRelativePath(T));
-  } else {
-    I.ReturnType = TypeInfo(D->getReturnType().getAsString());
-  }
+  I.ReturnType = getTypeInfoForType(D->getReturnType());
   parseParameters(I, D);
 }
 


        


More information about the cfe-commits mailing list