diff --git a/clang/include/clang/ExtractAPI/API.h b/clang/include/clang/ExtractAPI/API.h index b855f460b9c7c..7b2d28f738e26 100644 --- a/clang/include/clang/ExtractAPI/API.h +++ b/clang/include/clang/ExtractAPI/API.h @@ -1117,7 +1117,9 @@ struct has_function_signature template <> struct has_function_signature : public std::true_type {}; template <> -struct has_function_signature : public std::true_type {}; +struct has_function_signature : public std::true_type {}; +template <> +struct has_function_signature : public std::true_type {}; template <> struct has_function_signature : public std::true_type { }; @@ -1126,7 +1128,8 @@ struct has_function_signature : public std::true_type {}; template struct has_access : public std::false_type {}; -template <> struct has_access : public std::true_type {}; +template <> struct has_access : public std::true_type {}; +template <> struct has_access : public std::true_type {}; template <> struct has_access : public std::true_type {}; template <> struct has_access : public std::true_type {}; @@ -1267,7 +1270,7 @@ class APISet { DeclarationFragments SubHeading, SymbolReference Context, AccessControl Access, bool IsFromSystemHeaderg); - CXXFieldRecord *addCXXField(CXXClassRecord *CXXClass, StringRef Name, + CXXFieldRecord *addCXXField(APIRecord *CXXClass, StringRef Name, StringRef USR, PresumedLoc Loc, AvailabilitySet Availabilities, const DocComment &Comment, @@ -1322,18 +1325,25 @@ class APISet { DeclarationFragments SubHeading, Template Template, bool IsFromSystemHeader); - CXXMethodRecord * - addCXXMethod(CXXClassRecord *CXXClassRecord, StringRef Name, StringRef USR, - PresumedLoc Loc, AvailabilitySet Availability, - const DocComment &Comment, DeclarationFragments Declaration, - DeclarationFragments SubHeading, FunctionSignature Signature, - bool IsStatic, AccessControl Access, bool IsFromSystemHeader); + CXXMethodRecord *addCXXInstanceMethod( + APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc, + AvailabilitySet Availability, const DocComment &Comment, + DeclarationFragments Declaration, DeclarationFragments SubHeading, + FunctionSignature Signature, AccessControl Access, + bool IsFromSystemHeader); + + CXXMethodRecord *addCXXStaticMethod( + APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc, + AvailabilitySet Availability, const DocComment &Comment, + DeclarationFragments Declaration, DeclarationFragments SubHeading, + FunctionSignature Signature, AccessControl Access, + bool IsFromSystemHeader); CXXMethodRecord *addCXXSpecialMethod( - CXXClassRecord *CXXClassRecord, StringRef Name, StringRef USR, - PresumedLoc Loc, AvailabilitySet Availability, const DocComment &Comment, + APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc, + AvailabilitySet Availability, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading, - FunctionSignature Signature, bool IsConstructor, AccessControl Access, + FunctionSignature Signature, AccessControl Access, bool IsFromSystemHeader); CXXMethodTemplateRecord *addCXXMethodTemplate( @@ -1508,6 +1518,13 @@ class APISet { const RecordMap &getCXXMethodTemplates() const { return CXXMethodTemplates; } + const RecordMap &getCXXInstanceMethods() const { + return CXXInstanceMethods; + } + const RecordMap &getCXXStaticMethods() const { + return CXXStaticMethods; + } + const RecordMap &getCXXFields() const { return CXXFields; } const RecordMap & getCXXMethodTemplateSpecializations() const { return CXXMethodTemplateSpecializations; @@ -1594,6 +1611,10 @@ class APISet { RecordMap Enums; RecordMap Structs; RecordMap CXXClasses; + RecordMap CXXFields; + RecordMap CXXMethods; + RecordMap CXXInstanceMethods; + RecordMap CXXStaticMethods; RecordMap CXXMethodTemplates; RecordMap CXXMethodTemplateSpecializations; diff --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h index dbe7f78cd3343..38239b09dd484 100644 --- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h +++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h @@ -50,6 +50,8 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor { bool VisitEnumDecl(const EnumDecl *Decl); + bool WalkUpFromFunctionDecl(const FunctionDecl *Decl); + bool WalkUpFromRecordDecl(const RecordDecl *Decl); bool WalkUpFromCXXRecordDecl(const CXXRecordDecl *Decl); @@ -78,6 +80,14 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor { bool VisitCXXMethodDecl(const CXXMethodDecl *Decl); + bool VisitFieldDecl(const FieldDecl *Decl); + + bool VisitCXXConversionDecl(const CXXConversionDecl *Decl); + + bool VisitCXXConstructorDecl(const CXXConstructorDecl *Decl); + + bool VisitCXXDestructorDecl(const CXXDestructorDecl *Decl); + bool VisitConceptDecl(const ConceptDecl *Decl); bool VisitClassTemplateSpecializationDecl( @@ -119,20 +129,6 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor { void recordStructFields(StructRecord *StructRecord, const RecordDecl::field_range Fields); - /// Collect API information for the class fields and associate with the parent - /// struct - void recordCXXFields(CXXClassRecord *CXXClassRecord, - const RecordDecl::field_range Fields); - - void recordCXXMethods(CXXClassRecord *CXXClassRecord, - const CXXRecordDecl::method_range Methods); - - void recordConversionMethod(CXXClassRecord *CXXClassRecord, - const CXXMethodDecl *SpecialCXXMethod); - - void recordSpecialCXXMethod(CXXClassRecord *CXXClassRecord, - const CXXMethodDecl *SpecialCXXMethod); - /// Collect API information for the Objective-C methods and associate with the /// parent container. void recordObjCMethods(ObjCContainerRecord *Container, @@ -378,6 +374,13 @@ bool ExtractAPIVisitorBase::VisitEnumDecl(const EnumDecl *Decl) { return true; } +template +bool ExtractAPIVisitorBase::WalkUpFromFunctionDecl( + const FunctionDecl *Decl) { + getDerivedExtractAPIVisitor().VisitFunctionDecl(Decl); + return true; +} + template bool ExtractAPIVisitorBase::WalkUpFromRecordDecl( const RecordDecl *Decl) { @@ -527,9 +530,6 @@ bool ExtractAPIVisitorBase::VisitCXXRecordDecl( CXXClassRecord->Bases = getBases(Decl); - getDerivedExtractAPIVisitor().recordCXXFields(CXXClassRecord, Decl->fields()); - getDerivedExtractAPIVisitor().recordCXXMethods(CXXClassRecord, - Decl->methods()); return true; } @@ -539,18 +539,12 @@ bool ExtractAPIVisitorBase::VisitCXXMethodDecl( if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) || Decl->isImplicit()) return true; - switch (Decl->getTemplatedKind()) { - case FunctionDecl::TK_MemberSpecialization: - case FunctionDecl::TK_FunctionTemplateSpecialization: - case FunctionDecl::TK_FunctionTemplate: - case FunctionDecl::TK_DependentFunctionTemplateSpecialization: - break; - case FunctionDecl::TK_NonTemplate: - case FunctionDecl::TK_DependentNonTemplate: + + if (isa(Decl)) + return true; + if (isa(Decl) || isa(Decl)) return true; - } - StringRef Name = Decl->getName(); StringRef USR = API.recordUSR(Decl); PresumedLoc Loc = Context.getSourceManager().getPresumedLoc(Decl->getLocation()); @@ -561,15 +555,18 @@ bool ExtractAPIVisitorBase::VisitCXXMethodDecl( Context.getDiagnostics()); DeclarationFragments SubHeading = DeclarationFragmentsBuilder::getSubHeading(Decl); + auto Access = DeclarationFragmentsBuilder::getAccessControl(Decl); + auto Signature = DeclarationFragmentsBuilder::getFunctionSignature(Decl); SmallString<128> ParentUSR; index::generateUSRForDecl(dyn_cast(Decl->getDeclContext()), ParentUSR); + auto *Parent = API.findRecordForUSR(ParentUSR); if (Decl->isTemplated()) { FunctionTemplateDecl *TemplateDecl = Decl->getDescribedFunctionTemplate(); API.addCXXMethodTemplate( - API.findRecordForUSR(ParentUSR), Name, USR, Loc, AvailabilitySet(Decl), - Comment, + API.findRecordForUSR(ParentUSR), Decl->getName(), USR, Loc, + AvailabilitySet(Decl), Comment, DeclarationFragmentsBuilder::getFragmentsForFunctionTemplate( TemplateDecl), SubHeading, DeclarationFragmentsBuilder::getFunctionSignature(Decl), @@ -577,13 +574,93 @@ bool ExtractAPIVisitorBase::VisitCXXMethodDecl( Template(TemplateDecl), isInSystemHeader(Decl)); } else if (Decl->getTemplateSpecializationInfo()) API.addCXXMethodTemplateSpec( - API.findRecordForUSR(ParentUSR), Name, USR, Loc, AvailabilitySet(Decl), - Comment, + Parent, Decl->getName(), USR, Loc, AvailabilitySet(Decl), Comment, DeclarationFragmentsBuilder:: getFragmentsForFunctionTemplateSpecialization(Decl), - SubHeading, DeclarationFragmentsBuilder::getFunctionSignature(Decl), - DeclarationFragmentsBuilder::getAccessControl(Decl), - isInSystemHeader(Decl)); + SubHeading, Signature, Access, isInSystemHeader(Decl)); + else if (Decl->isOverloadedOperator()) + API.addCXXInstanceMethod( + Parent, API.copyString(Decl->getNameAsString()), USR, Loc, + AvailabilitySet(Decl), Comment, + DeclarationFragmentsBuilder::getFragmentsForOverloadedOperator(Decl), + SubHeading, Signature, Access, isInSystemHeader(Decl)); + else if (Decl->isStatic()) + API.addCXXStaticMethod( + Parent, Decl->getName(), USR, Loc, AvailabilitySet(Decl), Comment, + DeclarationFragmentsBuilder::getFragmentsForCXXMethod(Decl), SubHeading, + Signature, Access, isInSystemHeader(Decl)); + else + API.addCXXInstanceMethod( + Parent, Decl->getName(), USR, Loc, AvailabilitySet(Decl), Comment, + DeclarationFragmentsBuilder::getFragmentsForCXXMethod(Decl), SubHeading, + Signature, Access, isInSystemHeader(Decl)); + + return true; +} + +template +bool ExtractAPIVisitorBase::VisitCXXConstructorDecl( + const CXXConstructorDecl *Decl) { + + StringRef Name = API.copyString(Decl->getNameAsString()); + StringRef USR = API.recordUSR(Decl); + PresumedLoc Loc = + Context.getSourceManager().getPresumedLoc(Decl->getLocation()); + DocComment Comment; + if (auto *RawComment = + getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) + Comment = RawComment->getFormattedLines(Context.getSourceManager(), + Context.getDiagnostics()); + + // Build declaration fragments, sub-heading, and signature for the method. + DeclarationFragments Declaration = + DeclarationFragmentsBuilder::getFragmentsForSpecialCXXMethod(Decl); + DeclarationFragments SubHeading = + DeclarationFragmentsBuilder::getSubHeading(Decl); + FunctionSignature Signature = + DeclarationFragmentsBuilder::getFunctionSignature(Decl); + AccessControl Access = DeclarationFragmentsBuilder::getAccessControl(Decl); + + SmallString<128> ParentUSR; + index::generateUSRForDecl(dyn_cast(Decl->getDeclContext()), + ParentUSR); + API.addCXXInstanceMethod(API.findRecordForUSR(ParentUSR), Name, USR, Loc, + AvailabilitySet(Decl), Comment, Declaration, + SubHeading, Signature, Access, + isInSystemHeader(Decl)); + return true; +} + +template +bool ExtractAPIVisitorBase::VisitCXXDestructorDecl( + const CXXDestructorDecl *Decl) { + + StringRef Name = API.copyString(Decl->getNameAsString()); + StringRef USR = API.recordUSR(Decl); + PresumedLoc Loc = + Context.getSourceManager().getPresumedLoc(Decl->getLocation()); + DocComment Comment; + if (auto *RawComment = + getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) + Comment = RawComment->getFormattedLines(Context.getSourceManager(), + Context.getDiagnostics()); + + // Build declaration fragments, sub-heading, and signature for the method. + DeclarationFragments Declaration = + DeclarationFragmentsBuilder::getFragmentsForSpecialCXXMethod(Decl); + DeclarationFragments SubHeading = + DeclarationFragmentsBuilder::getSubHeading(Decl); + FunctionSignature Signature = + DeclarationFragmentsBuilder::getFunctionSignature(Decl); + AccessControl Access = DeclarationFragmentsBuilder::getAccessControl(Decl); + + SmallString<128> ParentUSR; + index::generateUSRForDecl(dyn_cast(Decl->getDeclContext()), + ParentUSR); + API.addCXXInstanceMethod(API.findRecordForUSR(ParentUSR), Name, USR, Loc, + AvailabilitySet(Decl), Comment, Declaration, + SubHeading, Signature, Access, + isInSystemHeader(Decl)); return true; } @@ -636,10 +713,7 @@ bool ExtractAPIVisitorBase::VisitClassTemplateSpecializationDecl( isInSystemHeader(Decl)); ClassTemplateSpecializationRecord->Bases = getBases(Decl); - getDerivedExtractAPIVisitor().recordCXXFields( - ClassTemplateSpecializationRecord, Decl->fields()); - getDerivedExtractAPIVisitor().recordCXXMethods( - ClassTemplateSpecializationRecord, Decl->methods()); + return true; } @@ -671,10 +745,6 @@ bool ExtractAPIVisitorBase:: ClassTemplatePartialSpecRecord->Bases = getBases(Decl); - getDerivedExtractAPIVisitor().recordCXXFields(ClassTemplatePartialSpecRecord, - Decl->fields()); - getDerivedExtractAPIVisitor().recordCXXMethods(ClassTemplatePartialSpecRecord, - Decl->methods()); return true; } @@ -1063,155 +1133,74 @@ void ExtractAPIVisitorBase::recordStructFields( } template -void ExtractAPIVisitorBase::recordCXXFields( - CXXClassRecord *CXXClassRecord, const RecordDecl::field_range Fields) { - for (const auto *Field : Fields) { - // Collect symbol information. - StringRef Name = Field->getName(); - StringRef USR = API.recordUSR(Field); - PresumedLoc Loc = - Context.getSourceManager().getPresumedLoc(Field->getLocation()); - Context.getSourceManager().getPresumedLoc(Field->getLocation()); - DocComment Comment; - if (auto *RawComment = - getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Field)) - Comment = RawComment->getFormattedLines(Context.getSourceManager(), - Context.getDiagnostics()); - - // Build declaration fragments and sub-heading for the struct field. - DeclarationFragments Declaration = - DeclarationFragmentsBuilder::getFragmentsForField(Field); - DeclarationFragments SubHeading = - DeclarationFragmentsBuilder::getSubHeading(Field); - AccessControl Access = DeclarationFragmentsBuilder::getAccessControl(Field); - - API.addCXXField(CXXClassRecord, Name, USR, Loc, AvailabilitySet(Field), - Comment, Declaration, SubHeading, Access, - isInSystemHeader(Field)); - } -} - -/// Collect API information for constructors and destructors and associate with -/// the parent class. -template -void ExtractAPIVisitorBase::recordSpecialCXXMethod( - CXXClassRecord *CXXClassRecord, const CXXMethodDecl *CXXSpecialMethod) { - StringRef Name; - bool isConstructor = false; - if (isa(CXXSpecialMethod)) { - isConstructor = true; - Name = CXXClassRecord->Name; - } else if (isa(CXXSpecialMethod)) { - // Copy string to get name with '~'. - Name = API.copyString(CXXSpecialMethod->getNameAsString()); - } - - StringRef USR = API.recordUSR(CXXSpecialMethod); - PresumedLoc Loc = Context.getSourceManager().getPresumedLoc( - CXXSpecialMethod->getLocation()); +bool ExtractAPIVisitorBase::VisitFieldDecl(const FieldDecl *Decl) { + if (Decl->getDeclContext()->getDeclKind() == Decl::Record) + return true; + if (isa(Decl)) + return true; + // Collect symbol information. + StringRef Name = Decl->getName(); + StringRef USR = API.recordUSR(Decl); + PresumedLoc Loc = + Context.getSourceManager().getPresumedLoc(Decl->getLocation()); DocComment Comment; - if (auto *RawComment = getDerivedExtractAPIVisitor().fetchRawCommentForDecl( - CXXSpecialMethod)) + if (auto *RawComment = + getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) Comment = RawComment->getFormattedLines(Context.getSourceManager(), Context.getDiagnostics()); - // Build declaration fragments, sub-heading, and signature for the method. + // Build declaration fragments and sub-heading for the struct field. DeclarationFragments Declaration = - DeclarationFragmentsBuilder::getFragmentsForSpecialCXXMethod( - CXXSpecialMethod); + DeclarationFragmentsBuilder::getFragmentsForField(Decl); DeclarationFragments SubHeading = - DeclarationFragmentsBuilder::getSubHeading(CXXSpecialMethod); - FunctionSignature Signature = - DeclarationFragmentsBuilder::getFunctionSignature(CXXSpecialMethod); - AccessControl Access = - DeclarationFragmentsBuilder::getAccessControl(CXXSpecialMethod); - - API.addCXXSpecialMethod(CXXClassRecord, Name, USR, Loc, - AvailabilitySet(CXXSpecialMethod), Comment, - Declaration, SubHeading, Signature, isConstructor, - Access, isInSystemHeader(CXXSpecialMethod)); + DeclarationFragmentsBuilder::getSubHeading(Decl); + AccessControl Access = DeclarationFragmentsBuilder::getAccessControl(Decl); + + SmallString<128> ParentUSR; + index::generateUSRForDecl(dyn_cast(Decl->getDeclContext()), + ParentUSR); + API.addCXXField(API.findRecordForUSR(ParentUSR), Name, USR, Loc, + AvailabilitySet(Decl), Comment, Declaration, SubHeading, + Access, isInSystemHeader(Decl)); + return true; } template -void ExtractAPIVisitorBase::recordConversionMethod( - CXXClassRecord *CXXClassRecord, const CXXMethodDecl *SpecialCXXMethod) { - StringRef Name = API.copyString(SpecialCXXMethod->getNameAsString()); - StringRef USR = API.recordUSR(SpecialCXXMethod); - PresumedLoc Loc = Context.getSourceManager().getPresumedLoc( - SpecialCXXMethod->getLocation()); +bool ExtractAPIVisitorBase::VisitCXXConversionDecl( + const CXXConversionDecl *Decl) { + StringRef Name = API.copyString(Decl->getNameAsString()); + StringRef USR = API.recordUSR(Decl); + PresumedLoc Loc = + Context.getSourceManager().getPresumedLoc(Decl->getLocation()); DocComment Comment; - if (auto *RawComment = getDerivedExtractAPIVisitor().fetchRawCommentForDecl( - SpecialCXXMethod)) + if (auto *RawComment = + getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) Comment = RawComment->getFormattedLines(Context.getSourceManager(), Context.getDiagnostics()); // Build declaration fragments, sub-heading, and signature for the method. DeclarationFragments Declaration = - DeclarationFragmentsBuilder::getFragmentsForConversionFunction( - cast(SpecialCXXMethod)); + DeclarationFragmentsBuilder::getFragmentsForConversionFunction(Decl); DeclarationFragments SubHeading = - DeclarationFragmentsBuilder::getSubHeading(SpecialCXXMethod); + DeclarationFragmentsBuilder::getSubHeading(Decl); FunctionSignature Signature = - DeclarationFragmentsBuilder::getFunctionSignature(SpecialCXXMethod); - AccessControl Access = - DeclarationFragmentsBuilder::getAccessControl(SpecialCXXMethod); - - API.addCXXMethod(CXXClassRecord, Name, USR, Loc, - AvailabilitySet(SpecialCXXMethod), Comment, Declaration, - SubHeading, Signature, SpecialCXXMethod->isStatic(), Access, - isInSystemHeader(SpecialCXXMethod)); -} - -template -void ExtractAPIVisitorBase::recordCXXMethods( - CXXClassRecord *CXXClassRecord, const CXXRecordDecl::method_range Methods) { - for (const auto *Method : Methods) { - if (isa(Method) || isa(Method)) { - recordSpecialCXXMethod(CXXClassRecord, Method); - continue; - } - - if (isa(Method)) { - recordConversionMethod(CXXClassRecord, Method); - continue; - } - - if (Method->isFunctionTemplateSpecialization()) - return; - - StringRef Name; - DeclarationFragments Declaration; - if (Method->isOverloadedOperator()) { - Name = API.copyString(Method->getNameAsString()); - Declaration = - DeclarationFragmentsBuilder::getFragmentsForOverloadedOperator( - Method); - } else { - Name = API.copyString(Method->getNameAsString()); - Declaration = - DeclarationFragmentsBuilder::getFragmentsForCXXMethod(Method); - } - StringRef USR = API.recordUSR(Method); - PresumedLoc Loc = - Context.getSourceManager().getPresumedLoc(Method->getLocation()); - DocComment Comment; - if (auto *RawComment = - getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Method)) - Comment = RawComment->getFormattedLines(Context.getSourceManager(), - Context.getDiagnostics()); - - // Build declaration fragments, sub-heading, and signature for the method. - DeclarationFragments SubHeading = - DeclarationFragmentsBuilder::getSubHeading(Method); - FunctionSignature Signature = - DeclarationFragmentsBuilder::getFunctionSignature(Method); - AccessControl Access = - DeclarationFragmentsBuilder::getAccessControl(Method); + DeclarationFragmentsBuilder::getFunctionSignature(Decl); + AccessControl Access = DeclarationFragmentsBuilder::getAccessControl(Decl); - API.addCXXMethod(CXXClassRecord, Name, USR, Loc, AvailabilitySet(Method), - Comment, Declaration, SubHeading, Signature, - Method->isStatic(), Access, isInSystemHeader(Method)); - } + SmallString<128> ParentUSR; + index::generateUSRForDecl(dyn_cast(Decl->getDeclContext()), + ParentUSR); + if (Decl->isStatic()) + API.addCXXStaticMethod(API.findRecordForUSR(ParentUSR), Name, USR, Loc, + AvailabilitySet(Decl), Comment, Declaration, + SubHeading, Signature, Access, + isInSystemHeader(Decl)); + else + API.addCXXInstanceMethod(API.findRecordForUSR(ParentUSR), Name, USR, Loc, + AvailabilitySet(Decl), Comment, Declaration, + SubHeading, Signature, Access, + isInSystemHeader(Decl)); + return true; } /// Collect API information for the Objective-C methods and associate with the diff --git a/clang/include/clang/ExtractAPI/Serialization/SerializerBase.h b/clang/include/clang/ExtractAPI/Serialization/SerializerBase.h index 34bb83a138233..269333245c836 100644 --- a/clang/include/clang/ExtractAPI/Serialization/SerializerBase.h +++ b/clang/include/clang/ExtractAPI/Serialization/SerializerBase.h @@ -39,10 +39,16 @@ template class APISetVisitor { getDerived()->traverseClassTemplatePartialSpecializationRecords(); + getDerived()->traverseCXXInstanceMethods(); + + getDerived()->traverseCXXStaticMethods(); + getDerived()->traverseCXXMethodTemplates(); getDerived()->traverseCXXMethodTemplateSpecializations(); + getDerived()->traverseCXXFields(); + getDerived()->traverseCXXFieldTemplates(); getDerived()->traverseConcepts(); @@ -131,6 +137,21 @@ template class APISetVisitor { *ClassTemplatePartialSpecialization.second); } + void traverseCXXInstanceMethods() { + for (const auto &InstanceMethod : API.getCXXInstanceMethods()) + getDerived()->visitCXXInstanceMethodRecord(*InstanceMethod.second); + } + + void traverseCXXStaticMethods() { + for (const auto &InstanceMethod : API.getCXXStaticMethods()) + getDerived()->visitCXXStaticMethodRecord(*InstanceMethod.second); + } + + void traverseCXXFields() { + for (const auto &CXXField : API.getCXXFields()) + getDerived()->visitCXXFieldRecord(*CXXField.second); + } + void traverseCXXFieldTemplates() { for (const auto &CXXFieldTemplate : API.getCXXFieldTemplates()) getDerived()->visitCXXFieldTemplateRecord(*CXXFieldTemplate.second); @@ -223,6 +244,10 @@ template class APISetVisitor { void visitClassTemplatePartialSpecializationRecord( const ClassTemplatePartialSpecializationRecord &Record){}; + void visitCXXInstanceRecord(const CXXInstanceMethodRecord &Record){}; + + void visitCXXStaticRecord(const CXXStaticMethodRecord &Record){}; + void visitMethodTemplateRecord(const CXXMethodTemplateRecord &Record){}; void visitMethodTemplateSpecializationRecord( diff --git a/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h b/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h index ca12c8f7a9b01..05cc33a0cb8c0 100644 --- a/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h +++ b/clang/include/clang/ExtractAPI/Serialization/SymbolGraphSerializer.h @@ -183,11 +183,17 @@ class SymbolGraphSerializer : public APISetVisitor { void visitClassTemplatePartialSpecializationRecord( const ClassTemplatePartialSpecializationRecord &Record); + void visitCXXInstanceMethodRecord(const CXXInstanceMethodRecord &Record); + + void visitCXXStaticMethodRecord(const CXXStaticMethodRecord &Record); + void visitMethodTemplateRecord(const CXXMethodTemplateRecord &Record); void visitMethodTemplateSpecializationRecord( const CXXMethodTemplateSpecializationRecord &Record); + void visitCXXFieldRecord(const CXXFieldRecord &Record); + void visitCXXFieldTemplateRecord(const CXXFieldTemplateRecord &Record); void visitConceptRecord(const ConceptRecord &Record); diff --git a/clang/lib/ExtractAPI/API.cpp b/clang/lib/ExtractAPI/API.cpp index 6cc00bc939c79..9e4cfe6dbab30 100644 --- a/clang/lib/ExtractAPI/API.cpp +++ b/clang/lib/ExtractAPI/API.cpp @@ -171,18 +171,17 @@ APISet::addStaticField(StringRef Name, StringRef USR, PresumedLoc Loc, } CXXFieldRecord * -APISet::addCXXField(CXXClassRecord *CXXClass, StringRef Name, StringRef USR, +APISet::addCXXField(APIRecord *CXXClass, StringRef Name, StringRef USR, PresumedLoc Loc, AvailabilitySet Availabilities, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading, AccessControl Access, bool IsFromSystemHeader) { - auto Record = std::make_unique( - USR, Name, Loc, std::move(Availabilities), Comment, Declaration, - SubHeading, Access, IsFromSystemHeader); + auto *Record = addTopLevelRecord( + USRBasedLookupTable, CXXFields, USR, Name, Loc, std::move(Availabilities), + Comment, Declaration, SubHeading, Access, IsFromSystemHeader); Record->ParentInformation = APIRecord::HierarchyInformation( CXXClass->USR, CXXClass->Name, CXXClass->getKind(), CXXClass); - USRBasedLookupTable.insert({USR, Record.get()}); - return CXXClass->Fields.emplace_back(std::move(Record)).get(); + return Record; } CXXFieldTemplateRecord *APISet::addCXXFieldTemplate( @@ -280,50 +279,38 @@ ConceptRecord *APISet::addConcept(StringRef Name, StringRef USR, SubHeading, Template, IsFromSystemHeader); } -CXXMethodRecord *APISet::addCXXMethod( - CXXClassRecord *CXXClassRecord, StringRef Name, StringRef USR, - PresumedLoc Loc, AvailabilitySet Availability, const DocComment &Comment, +CXXMethodRecord *APISet::addCXXInstanceMethod( + APIRecord *CXXClassRecord, StringRef Name, StringRef USR, PresumedLoc Loc, + AvailabilitySet Availability, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading, - FunctionSignature Signature, bool IsStatic, AccessControl Access, + FunctionSignature Signature, AccessControl Access, bool IsFromSystemHeader) { - std::unique_ptr Record; - if (IsStatic) - Record = std::make_unique( - USR, Name, Loc, std::move(Availability), Comment, Declaration, - SubHeading, Signature, Access, IsFromSystemHeader); - else - Record = std::make_unique( - USR, Name, Loc, std::move(Availability), Comment, Declaration, - SubHeading, Signature, Access, IsFromSystemHeader); + CXXMethodRecord *Record = + addTopLevelRecord(USRBasedLookupTable, CXXInstanceMethods, USR, Name, Loc, + std::move(Availability), Comment, Declaration, + SubHeading, Signature, Access, IsFromSystemHeader); Record->ParentInformation = APIRecord::HierarchyInformation( CXXClassRecord->USR, CXXClassRecord->Name, CXXClassRecord->getKind(), CXXClassRecord); - USRBasedLookupTable.insert({USR, Record.get()}); - return CXXClassRecord->Methods.emplace_back(std::move(Record)).get(); + return Record; } -CXXMethodRecord *APISet::addCXXSpecialMethod( - CXXClassRecord *CXXClassRecord, StringRef Name, StringRef USR, - PresumedLoc Loc, AvailabilitySet Availability, const DocComment &Comment, +CXXMethodRecord *APISet::addCXXStaticMethod( + APIRecord *CXXClassRecord, StringRef Name, StringRef USR, PresumedLoc Loc, + AvailabilitySet Availability, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading, - FunctionSignature Signature, bool IsConstructor, AccessControl Access, + FunctionSignature Signature, AccessControl Access, bool IsFromSystemHeader) { - std::unique_ptr Record; - if (IsConstructor) - Record = std::make_unique( - USR, Name, Loc, std::move(Availability), Comment, Declaration, - SubHeading, Signature, Access, IsFromSystemHeader); - else - Record = std::make_unique( - USR, Name, Loc, std::move(Availability), Comment, Declaration, - SubHeading, Signature, Access, IsFromSystemHeader); + CXXMethodRecord *Record = + addTopLevelRecord(USRBasedLookupTable, CXXStaticMethods, USR, Name, Loc, + std::move(Availability), Comment, Declaration, + SubHeading, Signature, Access, IsFromSystemHeader); Record->ParentInformation = APIRecord::HierarchyInformation( CXXClassRecord->USR, CXXClassRecord->Name, CXXClassRecord->getKind(), CXXClassRecord); - USRBasedLookupTable.insert({USR, Record.get()}); - return CXXClassRecord->Methods.emplace_back(std::move(Record)).get(); + return Record; } CXXMethodTemplateRecord *APISet::addCXXMethodTemplate( diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index 6782483681a0b..e1b5f652764f1 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -885,9 +885,6 @@ void SymbolGraphSerializer::visitCXXClassRecord(const CXXClassRecord &Record) { return; Symbols.emplace_back(std::move(*Class)); - serializeMembers(Record, Record.Fields); - serializeMembers(Record, Record.Methods); - for (const auto Base : Record.Bases) serializeRelationship(RelationshipKind::InheritsFrom, Record, Base); } @@ -899,9 +896,6 @@ void SymbolGraphSerializer::visitClassTemplateRecord( return; Symbols.emplace_back(std::move(*Class)); - serializeMembers(Record, Record.Fields); - serializeMembers(Record, Record.Methods); - for (const auto Base : Record.Bases) serializeRelationship(RelationshipKind::InheritsFrom, Record, Base); } @@ -913,8 +907,6 @@ void SymbolGraphSerializer::visitClassTemplateSpecializationRecord( return; Symbols.emplace_back(std::move(*Class)); - serializeMembers(Record, Record.Fields); - serializeMembers(Record, Record.Methods); for (const auto Base : Record.Bases) serializeRelationship(RelationshipKind::InheritsFrom, Record, Base); @@ -927,13 +919,33 @@ void SymbolGraphSerializer::visitClassTemplatePartialSpecializationRecord( return; Symbols.emplace_back(std::move(*Class)); - serializeMembers(Record, Record.Fields); - serializeMembers(Record, Record.Methods); for (const auto Base : Record.Bases) serializeRelationship(RelationshipKind::InheritsFrom, Record, Base); } +void SymbolGraphSerializer::visitCXXInstanceMethodRecord( + const CXXInstanceMethodRecord &Record) { + auto InstanceMethod = serializeAPIRecord(Record); + if (!InstanceMethod) + return; + + Symbols.emplace_back(std::move(*InstanceMethod)); + serializeRelationship(RelationshipKind::MemberOf, Record, + Record.ParentInformation.ParentRecord); +} + +void SymbolGraphSerializer::visitCXXStaticMethodRecord( + const CXXStaticMethodRecord &Record) { + auto StaticMethod = serializeAPIRecord(Record); + if (!StaticMethod) + return; + + Symbols.emplace_back(std::move(*StaticMethod)); + serializeRelationship(RelationshipKind::MemberOf, Record, + Record.ParentInformation.ParentRecord); +} + void SymbolGraphSerializer::visitMethodTemplateRecord( const CXXMethodTemplateRecord &Record) { if (!ShouldRecurse) @@ -960,6 +972,17 @@ void SymbolGraphSerializer::visitMethodTemplateSpecializationRecord( Record.ParentInformation.ParentRecord); } +void SymbolGraphSerializer::visitCXXFieldRecord(const CXXFieldRecord &Record) { + if (!ShouldRecurse) + return; + auto CXXField = serializeAPIRecord(Record); + if (!CXXField) + return; + Symbols.emplace_back(std::move(*CXXField)); + serializeRelationship(RelationshipKind::MemberOf, Record, + Record.ParentInformation.ParentRecord); +} + void SymbolGraphSerializer::visitCXXFieldTemplateRecord( const CXXFieldTemplateRecord &Record) { if (!ShouldRecurse) diff --git a/clang/test/ExtractAPI/constructor_destructor.cpp b/clang/test/ExtractAPI/constructor_destructor.cpp index 63048d1a4baed..65a924b53d69c 100644 --- a/clang/test/ExtractAPI/constructor_destructor.cpp +++ b/clang/test/ExtractAPI/constructor_destructor.cpp @@ -137,7 +137,7 @@ class Foo { "precise": "c:@S@Foo@F@Foo#" }, "kind": { - "displayName": "Constructor", + "displayName": "Instance Method", "identifier": "c++.method" }, "location": { @@ -193,7 +193,7 @@ class Foo { "precise": "c:@S@Foo@F@~Foo#" }, "kind": { - "displayName": "Destructor", + "displayName": "Instance Method", "identifier": "c++.method" }, "location": { diff --git a/clang/test/ExtractAPI/methods.cpp b/clang/test/ExtractAPI/methods.cpp index aed21c6afba82..f25f9ecf0605c 100644 --- a/clang/test/ExtractAPI/methods.cpp +++ b/clang/test/ExtractAPI/methods.cpp @@ -64,13 +64,13 @@ class Foo { }, { "kind": "memberOf", - "source": "c:@S@Foo@F@getFoo#S", + "source": "c:@S@Foo@F@getBar#1", "target": "c:@S@Foo", "targetFallback": "Foo" }, { "kind": "memberOf", - "source": "c:@S@Foo@F@getBar#1", + "source": "c:@S@Foo@F@getFoo#S", "target": "c:@S@Foo", "targetFallback": "Foo" } @@ -310,11 +310,11 @@ class Foo { ] }, { - "accessLevel": "public", + "accessLevel": "protected", "declarationFragments": [ { "kind": "keyword", - "spelling": "static" + "spelling": "constexpr" }, { "kind": "text", @@ -322,8 +322,8 @@ class Foo { }, { "kind": "typeIdentifier", - "preciseIdentifier": "c:d", - "spelling": "double" + "preciseIdentifier": "c:I", + "spelling": "int" }, { "kind": "text", @@ -331,34 +331,42 @@ class Foo { }, { "kind": "identifier", - "spelling": "getFoo" + "spelling": "getBar" }, { "kind": "text", - "spelling": "();" + "spelling": "() " + }, + { + "kind": "keyword", + "spelling": "const" + }, + { + "kind": "text", + "spelling": ";" } ], "functionSignature": { "returns": [ { "kind": "typeIdentifier", - "preciseIdentifier": "c:d", - "spelling": "double" + "preciseIdentifier": "c:I", + "spelling": "int" } ] }, "identifier": { "interfaceLanguage": "c++", - "precise": "c:@S@Foo@F@getFoo#S" + "precise": "c:@S@Foo@F@getBar#1" }, "kind": { - "displayName": "Static Method", - "identifier": "c++.type.method" + "displayName": "Instance Method", + "identifier": "c++.method" }, "location": { "position": { "character": 17, - "line": 7 + "line": 10 }, "uri": "file://INPUT_DIR/input.h" }, @@ -366,28 +374,28 @@ class Foo { "navigator": [ { "kind": "identifier", - "spelling": "getFoo" + "spelling": "getBar" } ], "subHeading": [ { "kind": "identifier", - "spelling": "getFoo" + "spelling": "getBar" } ], - "title": "getFoo" + "title": "getBar" }, "pathComponents": [ "Foo", - "getFoo" + "getBar" ] }, { - "accessLevel": "protected", + "accessLevel": "public", "declarationFragments": [ { "kind": "keyword", - "spelling": "constexpr" + "spelling": "static" }, { "kind": "text", @@ -395,8 +403,8 @@ class Foo { }, { "kind": "typeIdentifier", - "preciseIdentifier": "c:I", - "spelling": "int" + "preciseIdentifier": "c:d", + "spelling": "double" }, { "kind": "text", @@ -404,42 +412,34 @@ class Foo { }, { "kind": "identifier", - "spelling": "getBar" - }, - { - "kind": "text", - "spelling": "() " - }, - { - "kind": "keyword", - "spelling": "const" + "spelling": "getFoo" }, { "kind": "text", - "spelling": ";" + "spelling": "();" } ], "functionSignature": { "returns": [ { "kind": "typeIdentifier", - "preciseIdentifier": "c:I", - "spelling": "int" + "preciseIdentifier": "c:d", + "spelling": "double" } ] }, "identifier": { "interfaceLanguage": "c++", - "precise": "c:@S@Foo@F@getBar#1" + "precise": "c:@S@Foo@F@getFoo#S" }, "kind": { - "displayName": "Instance Method", - "identifier": "c++.method" + "displayName": "Static Method", + "identifier": "c++.type.method" }, "location": { "position": { "character": 17, - "line": 10 + "line": 7 }, "uri": "file://INPUT_DIR/input.h" }, @@ -447,20 +447,20 @@ class Foo { "navigator": [ { "kind": "identifier", - "spelling": "getBar" + "spelling": "getFoo" } ], "subHeading": [ { "kind": "identifier", - "spelling": "getBar" + "spelling": "getFoo" } ], - "title": "getBar" + "title": "getFoo" }, "pathComponents": [ "Foo", - "getBar" + "getFoo" ] } ]