https://github.com/daniel-grumberg created https://github.com/llvm/llvm-project/pull/73369
Ensure that block types get represented correctly in declaration fragments, as block parameter names are important for documentation clients we need a separate system from getFragmentsForType in order to have access to full ParmVarDecls for the parameters. rdar://118257401 >From e0a9db8aa5e511e81836b5f8e59853c0b498cadf Mon Sep 17 00:00:00 2001 From: Daniel Grumberg <dgrumb...@apple.com> Date: Fri, 24 Nov 2023 20:34:49 +0000 Subject: [PATCH] [clang][ExtractAPI] Add support for blocks in declaration fragments Ensure that block types get represented correctly in declaration fragments, as block parameter names are important for documentation clients we need a separate system from getFragmentsForType in order to have access to full ParmVarDecls for the parameters. rdar://118257401 --- .../clang/ExtractAPI/DeclarationFragments.h | 6 + clang/lib/ExtractAPI/DeclarationFragments.cpp | 176 +++- clang/test/ExtractAPI/objc_block.m | 965 ++++++++++++++++++ clang/test/ExtractAPI/objc_category.m | 4 + clang/test/ExtractAPI/objc_id_protocol.m | 8 + clang/test/ExtractAPI/objc_interface.m | 4 + clang/test/ExtractAPI/objc_property.m | 24 + 7 files changed, 1159 insertions(+), 28 deletions(-) create mode 100644 clang/test/ExtractAPI/objc_block.m diff --git a/clang/include/clang/ExtractAPI/DeclarationFragments.h b/clang/include/clang/ExtractAPI/DeclarationFragments.h index 316d83df13e9359..d719196b9a43ecb 100644 --- a/clang/include/clang/ExtractAPI/DeclarationFragments.h +++ b/clang/include/clang/ExtractAPI/DeclarationFragments.h @@ -24,6 +24,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/TypeLoc.h" #include "clang/Basic/Specifiers.h" #include "clang/Lex/MacroInfo.h" #include "llvm/ADT/SmallVector.h" @@ -410,6 +411,11 @@ class DeclarationFragmentsBuilder { /// Build DeclarationFragments for a parameter variable declaration /// ParmVarDecl. static DeclarationFragments getFragmentsForParam(const ParmVarDecl *); + + static DeclarationFragments + getFragmentsForBlock(const NamedDecl *BlockDecl, FunctionTypeLoc &Block, + FunctionProtoTypeLoc &BlockProto, + DeclarationFragments &After); }; template <typename FunctionT> diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp index 02fa6cd6119ecac..eb6eea0aaf54655 100644 --- a/clang/lib/ExtractAPI/DeclarationFragments.cpp +++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp @@ -15,6 +15,8 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/QualTypeNames.h" +#include "clang/AST/Type.h" +#include "clang/AST/TypeLoc.h" #include "clang/Basic/OperatorKinds.h" #include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h" #include "clang/Index/USRGeneration.h" @@ -24,6 +26,40 @@ using namespace clang::extractapi; using namespace llvm; +namespace { + +void findTypeLocForBlockDecl(const clang::TypeSourceInfo *TSInfo, + clang::FunctionTypeLoc &Block, + clang::FunctionProtoTypeLoc &BlockProto) { + if (!TSInfo) + return; + + clang::TypeLoc TL = TSInfo->getTypeLoc().getUnqualifiedLoc(); + while (true) { + // Look through qualified types + if (auto QualifiedTL = TL.getAs<clang::QualifiedTypeLoc>()) { + TL = QualifiedTL.getUnqualifiedLoc(); + continue; + } + + if (auto AttrTL = TL.getAs<clang::AttributedTypeLoc>()) { + TL = AttrTL.getModifiedLoc(); + continue; + } + + // Try to get the function prototype behind the block pointer type, + // then we're done. + if (auto BlockPtr = TL.getAs<clang::BlockPointerTypeLoc>()) { + TL = BlockPtr.getPointeeLoc().IgnoreParens(); + Block = TL.getAs<clang::FunctionTypeLoc>(); + BlockProto = TL.getAs<clang::FunctionProtoTypeLoc>(); + } + break; + } +} + +} // namespace + DeclarationFragments &DeclarationFragments::appendSpace() { if (!Fragments.empty()) { Fragment &Last = Fragments.back(); @@ -218,7 +254,7 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType( // Declaration fragments of a pointer type is the declaration fragments of // the pointee type followed by a `*`, - if (T->isPointerType()) + if (T->isPointerType() && !T->isFunctionPointerType()) return Fragments .append(getFragmentsForType(T->getPointeeType(), Context, After)) .append(" *", DeclarationFragments::FragmentKind::Text); @@ -449,10 +485,6 @@ DeclarationFragmentsBuilder::getFragmentsForVar(const VarDecl *Var) { .append(VarDecl::getStorageClassSpecifierString(SC), DeclarationFragments::FragmentKind::Keyword) .appendSpace(); - QualType T = - Var->getTypeSourceInfo() - ? Var->getTypeSourceInfo()->getType() - : Var->getASTContext().getUnqualifiedObjCPointerType(Var->getType()); // Capture potential fragments that needs to be placed after the variable name // ``` @@ -460,8 +492,23 @@ DeclarationFragmentsBuilder::getFragmentsForVar(const VarDecl *Var) { // char (*ptr_to_array)[6]; // ``` DeclarationFragments After; - return Fragments.append(getFragmentsForType(T, Var->getASTContext(), After)) - .appendSpace() + FunctionTypeLoc BlockLoc; + FunctionProtoTypeLoc BlockProtoLoc; + findTypeLocForBlockDecl(Var->getTypeSourceInfo(), BlockLoc, BlockProtoLoc); + + if (!BlockLoc) { + QualType T = Var->getTypeSourceInfo() + ? Var->getTypeSourceInfo()->getType() + : Var->getASTContext().getUnqualifiedObjCPointerType( + Var->getType()); + + Fragments.append(getFragmentsForType(T, Var->getASTContext(), After)) + .appendSpace(); + } else { + Fragments.append(getFragmentsForBlock(Var, BlockLoc, BlockProtoLoc, After)); + } + + return Fragments .append(Var->getName(), DeclarationFragments::FragmentKind::Identifier) .append(std::move(After)) .append(";", DeclarationFragments::FragmentKind::Text); @@ -504,13 +551,23 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForParam(const ParmVarDecl *Param) { DeclarationFragments Fragments, After; - QualType T = Param->getTypeSourceInfo() - ? Param->getTypeSourceInfo()->getType() - : Param->getASTContext().getUnqualifiedObjCPointerType( - Param->getType()); + auto *TSInfo = Param->getTypeSourceInfo(); + + QualType T = TSInfo ? TSInfo->getType() + : Param->getASTContext().getUnqualifiedObjCPointerType( + Param->getType()); + + FunctionTypeLoc BlockLoc; + FunctionProtoTypeLoc BlockProtoLoc; + findTypeLocForBlockDecl(TSInfo, BlockLoc, BlockProtoLoc); + + DeclarationFragments TypeFragments; + if (BlockLoc) + TypeFragments.append( + getFragmentsForBlock(Param, BlockLoc, BlockProtoLoc, After)); + else + TypeFragments.append(getFragmentsForType(T, Param->getASTContext(), After)); - DeclarationFragments TypeFragments = - getFragmentsForType(T, Param->getASTContext(), After); if (TypeFragments.begin()->Spelling.substr(0, 14).compare("type-parameter") == 0) { std::string ProperArgName = getNameForTemplateArgument( @@ -522,17 +579,60 @@ DeclarationFragmentsBuilder::getFragmentsForParam(const ParmVarDecl *Param) { TypeFragments.begin()->Spelling.swap(ProperArgName); } - if (Param->isObjCMethodParameter()) + if (Param->isObjCMethodParameter()) { Fragments.append("(", DeclarationFragments::FragmentKind::Text) .append(std::move(TypeFragments)) - .append(") ", DeclarationFragments::FragmentKind::Text); - else - Fragments.append(std::move(TypeFragments)).appendSpace(); + .append(std::move(After)) + .append(") ", DeclarationFragments::FragmentKind::Text) + .append(Param->getName(), + DeclarationFragments::FragmentKind::InternalParam); + } else { + Fragments.append(std::move(TypeFragments)); + if (!T->isBlockPointerType()) + Fragments.appendSpace(); + Fragments + .append(Param->getName(), + DeclarationFragments::FragmentKind::InternalParam) + .append(std::move(After)); + } + return Fragments; +} - return Fragments - .append(Param->getName(), - DeclarationFragments::FragmentKind::InternalParam) - .append(std::move(After)); +DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForBlock( + const NamedDecl *BlockDecl, FunctionTypeLoc &Block, + FunctionProtoTypeLoc &BlockProto, DeclarationFragments &After) { + DeclarationFragments Fragments; + + DeclarationFragments RetTyAfter; + auto ReturnValueFragment = getFragmentsForType( + Block.getTypePtr()->getReturnType(), BlockDecl->getASTContext(), After); + + Fragments.append(std::move(ReturnValueFragment)) + .append(std::move(RetTyAfter)) + .appendSpace() + .append("(^", DeclarationFragments::FragmentKind::Text); + + After.append(")", DeclarationFragments::FragmentKind::Text); + unsigned NumParams = Block.getNumParams(); + + if (!BlockProto || NumParams == 0) { + if (BlockProto && BlockProto.getTypePtr()->isVariadic()) + After.append("(...)", DeclarationFragments::FragmentKind::Text); + else + After.append("()", DeclarationFragments::FragmentKind::Text); + } else { + After.append("(", DeclarationFragments::FragmentKind::Text); + for (unsigned I = 0; I != NumParams; ++I) { + if (I) + After.append(", ", DeclarationFragments::FragmentKind::Text); + After.append(getFragmentsForParam(Block.getParam(I))); + if (I == NumParams - 1 && BlockProto.getTypePtr()->isVariadic()) + After.append(", ...", DeclarationFragments::FragmentKind::Text); + } + After.append(")", DeclarationFragments::FragmentKind::Text); + } + + return Fragments; } DeclarationFragments @@ -595,11 +695,18 @@ DeclarationFragmentsBuilder::getFragmentsForFunction(const FunctionDecl *Func) { Fragments.append(std::move(After)); Fragments.append("(", DeclarationFragments::FragmentKind::Text); - for (unsigned i = 0, end = Func->getNumParams(); i != end; ++i) { + unsigned NumParams = Func->getNumParams(); + for (unsigned i = 0; i != NumParams; ++i) { if (i) Fragments.append(", ", DeclarationFragments::FragmentKind::Text); Fragments.append(getFragmentsForParam(Func->getParamDecl(i))); } + + if (Func->isVariadic()) { + if (NumParams > 0) + Fragments.append(", ", DeclarationFragments::FragmentKind::Text); + Fragments.append("...", DeclarationFragments::FragmentKind::Text); + } Fragments.append(")", DeclarationFragments::FragmentKind::Text); Fragments.append(DeclarationFragments::getExceptionSpecificationString( @@ -1248,14 +1355,27 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProperty( Fragments.append(")", DeclarationFragments::FragmentKind::Text); } - // Build the property type and name, and return the completed fragments. - return Fragments.appendSpace() - .append(getFragmentsForType(Property->getType(), - Property->getASTContext(), After)) - .appendSpace() + Fragments.appendSpace(); + + FunctionTypeLoc BlockLoc; + FunctionProtoTypeLoc BlockProtoLoc; + findTypeLocForBlockDecl(Property->getTypeSourceInfo(), BlockLoc, + BlockProtoLoc); + + auto PropType = Property->getType(); + if (!BlockLoc) + Fragments + .append(getFragmentsForType(PropType, Property->getASTContext(), After)) + .appendSpace(); + else + Fragments.append( + getFragmentsForBlock(Property, BlockLoc, BlockProtoLoc, After)); + + return Fragments .append(Property->getName(), DeclarationFragments::FragmentKind::Identifier) - .append(std::move(After)); + .append(std::move(After)) + .append(";", DeclarationFragments::FragmentKind::Text); } DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProtocol( diff --git a/clang/test/ExtractAPI/objc_block.m b/clang/test/ExtractAPI/objc_block.m new file mode 100644 index 000000000000000..a7a4f5696333c18 --- /dev/null +++ b/clang/test/ExtractAPI/objc_block.m @@ -0,0 +1,965 @@ +// RUN: rm -rf %t +// RUN: split-file %s %t +// RUN: sed -e "s@INPUT_DIR@%{/t:regex_replacement}@g" \ +// RUN: %t/reference.output.json.in >> %t/reference.output.json +// RUN: %clang_cc1 -extract-api -fblocks -triple arm64-apple-macosx \ +// RUN: -x objective-c-header %t/input.h -o %t/output.json -verify + +// Generator version is not consistent across test runs, normalize it. +// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \ +// RUN: %t/output.json >> %t/output-normalized.json +// RUN: diff %t/reference.output.json %t/output-normalized.json + +//--- input.h +@interface Foo +-(void)methodBlockNoParam:(void (^)())block; +-(void)methodBlockWithParam:(int (^)(int foo))block; +-(void)methodBlockWithMultipleParam:(int (^)(int foo, unsigned baz))block; +-(void)methodBlockVariadic:(int (^)(int foo, ...))block; +@end + +void func(int (^arg)(int foo)); + +int (^global)(int foo); + +///expected-no-diagnostics + +//--- reference.output.json.in +{ + "metadata": { + "formatVersion": { + "major": 0, + "minor": 5, + "patch": 3 + }, + "generator": "?" + }, + "module": { + "name": "", + "platform": { + "architecture": "arm64", + "operatingSystem": { + "minimumVersion": { + "major": 11, + "minor": 0, + "patch": 0 + }, + "name": "macosx" + }, + "vendor": "apple" + } + }, + "relationships": [ + { + "kind": "memberOf", + "source": "c:objc(cs)Foo(im)methodBlockNoParam:", + "target": "c:objc(cs)Foo", + "targetFallback": "Foo" + }, + { + "kind": "memberOf", + "source": "c:objc(cs)Foo(im)methodBlockWithParam:", + "target": "c:objc(cs)Foo", + "targetFallback": "Foo" + }, + { + "kind": "memberOf", + "source": "c:objc(cs)Foo(im)methodBlockWithMultipleParam:", + "target": "c:objc(cs)Foo", + "targetFallback": "Foo" + }, + { + "kind": "memberOf", + "source": "c:objc(cs)Foo(im)methodBlockVariadic:", + "target": "c:objc(cs)Foo", + "targetFallback": "Foo" + } + ], + "symbols": [ + { + "accessLevel": "public", + "declarationFragments": [ + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:I", + "spelling": "int" + }, + { + "kind": "text", + "spelling": " (^" + }, + { + "kind": "identifier", + "spelling": "global" + }, + { + "kind": "text", + "spelling": ")(" + }, + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:I", + "spelling": "int" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "foo" + }, + { + "kind": "text", + "spelling": ");" + } + ], + "identifier": { + "interfaceLanguage": "objective-c", + "precise": "c:@global" + }, + "kind": { + "displayName": "Global Variable", + "identifier": "objective-c.var" + }, + "location": { + "position": { + "character": 6, + "line": 9 + }, + "uri": "file://INPUT_DIR/input.h" + }, + "names": { + "navigator": [ + { + "kind": "identifier", + "spelling": "global" + } + ], + "subHeading": [ + { + "kind": "identifier", + "spelling": "global" + } + ], + "title": "global" + }, + "pathComponents": [ + "global" + ] + }, + { + "accessLevel": "public", + "declarationFragments": [ + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:v", + "spelling": "void" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "func" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:I", + "spelling": "int" + }, + { + "kind": "text", + "spelling": " (^" + }, + { + "kind": "internalParam", + "spelling": "arg" + }, + { + "kind": "text", + "spelling": ")(" + }, + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:I", + "spelling": "int" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "foo" + }, + { + "kind": "text", + "spelling": "));" + } + ], + "functionSignature": { + "parameters": [ + { + "declarationFragments": [ + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:I", + "spelling": "int" + }, + { + "kind": "text", + "spelling": " (^" + }, + { + "kind": "internalParam", + "spelling": "arg" + }, + { + "kind": "text", + "spelling": ")(" + }, + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:I", + "spelling": "int" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "foo" + }, + { + "kind": "text", + "spelling": ")" + } + ], + "name": "arg" + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:v", + "spelling": "void" + } + ] + }, + "identifier": { + "interfaceLanguage": "objective-c", + "precise": "c:@F@func" + }, + "kind": { + "displayName": "Function", + "identifier": "objective-c.func" + }, + "location": { + "position": { + "character": 5, + "line": 7 + }, + "uri": "file://INPUT_DIR/input.h" + }, + "names": { + "navigator": [ + { + "kind": "identifier", + "spelling": "func" + } + ], + "subHeading": [ + { + "kind": "identifier", + "spelling": "func" + } + ], + "title": "func" + }, + "pathComponents": [ + "func" + ] + }, + { + "accessLevel": "public", + "declarationFragments": [ + { + "kind": "keyword", + "spelling": "@interface" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "identifier", + "spelling": "Foo" + } + ], + "identifier": { + "interfaceLanguage": "objective-c", + "precise": "c:objc(cs)Foo" + }, + "kind": { + "displayName": "Class", + "identifier": "objective-c.class" + }, + "location": { + "position": { + "character": 11, + "line": 0 + }, + "uri": "file://INPUT_DIR/input.h" + }, + "names": { + "navigator": [ + { + "kind": "identifier", + "spelling": "Foo" + } + ], + "subHeading": [ + { + "kind": "identifier", + "spelling": "Foo" + } + ], + "title": "Foo" + }, + "pathComponents": [ + "Foo" + ] + }, + { + "accessLevel": "public", + "declarationFragments": [ + { + "kind": "text", + "spelling": "- (" + }, + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:v", + "spelling": "void" + }, + { + "kind": "text", + "spelling": ") " + }, + { + "kind": "identifier", + "spelling": "methodBlockNoParam:" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:v", + "spelling": "void" + }, + { + "kind": "text", + "spelling": " (^" + }, + { + "kind": "text", + "spelling": ")()) " + }, + { + "kind": "internalParam", + "spelling": "block" + }, + { + "kind": "text", + "spelling": ";" + } + ], + "functionSignature": { + "parameters": [ + { + "declarationFragments": [ + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:v", + "spelling": "void" + }, + { + "kind": "text", + "spelling": " (^" + }, + { + "kind": "text", + "spelling": ")()) " + }, + { + "kind": "internalParam", + "spelling": "block" + } + ], + "name": "block" + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:v", + "spelling": "void" + } + ] + }, + "identifier": { + "interfaceLanguage": "objective-c", + "precise": "c:objc(cs)Foo(im)methodBlockNoParam:" + }, + "kind": { + "displayName": "Instance Method", + "identifier": "objective-c.method" + }, + "location": { + "position": { + "character": 0, + "line": 1 + }, + "uri": "file://INPUT_DIR/input.h" + }, + "names": { + "navigator": [ + { + "kind": "identifier", + "spelling": "methodBlockNoParam:" + } + ], + "subHeading": [ + { + "kind": "text", + "spelling": "- " + }, + { + "kind": "identifier", + "spelling": "methodBlockNoParam:" + } + ], + "title": "methodBlockNoParam:" + }, + "pathComponents": [ + "Foo", + "methodBlockNoParam:" + ] + }, + { + "accessLevel": "public", + "declarationFragments": [ + { + "kind": "text", + "spelling": "- (" + }, + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:v", + "spelling": "void" + }, + { + "kind": "text", + "spelling": ") " + }, + { + "kind": "identifier", + "spelling": "methodBlockWithParam:" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:I", + "spelling": "int" + }, + { + "kind": "text", + "spelling": " (^" + }, + { + "kind": "text", + "spelling": ")(" + }, + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:I", + "spelling": "int" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "foo" + }, + { + "kind": "text", + "spelling": ")) " + }, + { + "kind": "internalParam", + "spelling": "block" + }, + { + "kind": "text", + "spelling": ";" + } + ], + "functionSignature": { + "parameters": [ + { + "declarationFragments": [ + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:I", + "spelling": "int" + }, + { + "kind": "text", + "spelling": " (^" + }, + { + "kind": "text", + "spelling": ")(" + }, + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:I", + "spelling": "int" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "foo" + }, + { + "kind": "text", + "spelling": ")) " + }, + { + "kind": "internalParam", + "spelling": "block" + } + ], + "name": "block" + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:v", + "spelling": "void" + } + ] + }, + "identifier": { + "interfaceLanguage": "objective-c", + "precise": "c:objc(cs)Foo(im)methodBlockWithParam:" + }, + "kind": { + "displayName": "Instance Method", + "identifier": "objective-c.method" + }, + "location": { + "position": { + "character": 0, + "line": 2 + }, + "uri": "file://INPUT_DIR/input.h" + }, + "names": { + "navigator": [ + { + "kind": "identifier", + "spelling": "methodBlockWithParam:" + } + ], + "subHeading": [ + { + "kind": "text", + "spelling": "- " + }, + { + "kind": "identifier", + "spelling": "methodBlockWithParam:" + } + ], + "title": "methodBlockWithParam:" + }, + "pathComponents": [ + "Foo", + "methodBlockWithParam:" + ] + }, + { + "accessLevel": "public", + "declarationFragments": [ + { + "kind": "text", + "spelling": "- (" + }, + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:v", + "spelling": "void" + }, + { + "kind": "text", + "spelling": ") " + }, + { + "kind": "identifier", + "spelling": "methodBlockWithMultipleParam:" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:I", + "spelling": "int" + }, + { + "kind": "text", + "spelling": " (^" + }, + { + "kind": "text", + "spelling": ")(" + }, + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:I", + "spelling": "int" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "foo" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:i", + "spelling": "unsigned int" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "baz" + }, + { + "kind": "text", + "spelling": ")) " + }, + { + "kind": "internalParam", + "spelling": "block" + }, + { + "kind": "text", + "spelling": ";" + } + ], + "functionSignature": { + "parameters": [ + { + "declarationFragments": [ + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:I", + "spelling": "int" + }, + { + "kind": "text", + "spelling": " (^" + }, + { + "kind": "text", + "spelling": ")(" + }, + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:I", + "spelling": "int" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "foo" + }, + { + "kind": "text", + "spelling": ", " + }, + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:i", + "spelling": "unsigned int" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "baz" + }, + { + "kind": "text", + "spelling": ")) " + }, + { + "kind": "internalParam", + "spelling": "block" + } + ], + "name": "block" + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:v", + "spelling": "void" + } + ] + }, + "identifier": { + "interfaceLanguage": "objective-c", + "precise": "c:objc(cs)Foo(im)methodBlockWithMultipleParam:" + }, + "kind": { + "displayName": "Instance Method", + "identifier": "objective-c.method" + }, + "location": { + "position": { + "character": 0, + "line": 3 + }, + "uri": "file://INPUT_DIR/input.h" + }, + "names": { + "navigator": [ + { + "kind": "identifier", + "spelling": "methodBlockWithMultipleParam:" + } + ], + "subHeading": [ + { + "kind": "text", + "spelling": "- " + }, + { + "kind": "identifier", + "spelling": "methodBlockWithMultipleParam:" + } + ], + "title": "methodBlockWithMultipleParam:" + }, + "pathComponents": [ + "Foo", + "methodBlockWithMultipleParam:" + ] + }, + { + "accessLevel": "public", + "declarationFragments": [ + { + "kind": "text", + "spelling": "- (" + }, + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:v", + "spelling": "void" + }, + { + "kind": "text", + "spelling": ") " + }, + { + "kind": "identifier", + "spelling": "methodBlockVariadic:" + }, + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:I", + "spelling": "int" + }, + { + "kind": "text", + "spelling": " (^" + }, + { + "kind": "text", + "spelling": ")(" + }, + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:I", + "spelling": "int" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "foo" + }, + { + "kind": "text", + "spelling": ", ...)) " + }, + { + "kind": "internalParam", + "spelling": "block" + }, + { + "kind": "text", + "spelling": ";" + } + ], + "functionSignature": { + "parameters": [ + { + "declarationFragments": [ + { + "kind": "text", + "spelling": "(" + }, + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:I", + "spelling": "int" + }, + { + "kind": "text", + "spelling": " (^" + }, + { + "kind": "text", + "spelling": ")(" + }, + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:I", + "spelling": "int" + }, + { + "kind": "text", + "spelling": " " + }, + { + "kind": "internalParam", + "spelling": "foo" + }, + { + "kind": "text", + "spelling": ", ...)) " + }, + { + "kind": "internalParam", + "spelling": "block" + } + ], + "name": "block" + } + ], + "returns": [ + { + "kind": "typeIdentifier", + "preciseIdentifier": "c:v", + "spelling": "void" + } + ] + }, + "identifier": { + "interfaceLanguage": "objective-c", + "precise": "c:objc(cs)Foo(im)methodBlockVariadic:" + }, + "kind": { + "displayName": "Instance Method", + "identifier": "objective-c.method" + }, + "location": { + "position": { + "character": 0, + "line": 4 + }, + "uri": "file://INPUT_DIR/input.h" + }, + "names": { + "navigator": [ + { + "kind": "identifier", + "spelling": "methodBlockVariadic:" + } + ], + "subHeading": [ + { + "kind": "text", + "spelling": "- " + }, + { + "kind": "identifier", + "spelling": "methodBlockVariadic:" + } + ], + "title": "methodBlockVariadic:" + }, + "pathComponents": [ + "Foo", + "methodBlockVariadic:" + ] + } + ] +} diff --git a/clang/test/ExtractAPI/objc_category.m b/clang/test/ExtractAPI/objc_category.m index 897bc082fdc033b..34b0a9e31f553c9 100644 --- a/clang/test/ExtractAPI/objc_category.m +++ b/clang/test/ExtractAPI/objc_category.m @@ -296,6 +296,10 @@ + (void)ClassMethod; { "kind": "identifier", "spelling": "Property" + }, + { + "kind": "text", + "spelling": ";" } ], "identifier": { diff --git a/clang/test/ExtractAPI/objc_id_protocol.m b/clang/test/ExtractAPI/objc_id_protocol.m index 4014541278a36b7..0b0f1b39d2bd61f 100644 --- a/clang/test/ExtractAPI/objc_id_protocol.m +++ b/clang/test/ExtractAPI/objc_id_protocol.m @@ -150,6 +150,10 @@ @interface MyInterface { "kind": "identifier", "spelling": "obj1" + }, + { + "kind": "text", + "spelling": ";" } ], "identifier": { @@ -218,6 +222,10 @@ @interface MyInterface { "kind": "identifier", "spelling": "obj2" + }, + { + "kind": "text", + "spelling": ";" } ], "identifier": { diff --git a/clang/test/ExtractAPI/objc_interface.m b/clang/test/ExtractAPI/objc_interface.m index c04f87998bb066c..ab1772a0c529bba 100644 --- a/clang/test/ExtractAPI/objc_interface.m +++ b/clang/test/ExtractAPI/objc_interface.m @@ -468,6 +468,10 @@ - (char)getIvar; { "kind": "identifier", "spelling": "Property" + }, + { + "kind": "text", + "spelling": ";" } ], "identifier": { diff --git a/clang/test/ExtractAPI/objc_property.m b/clang/test/ExtractAPI/objc_property.m index 5a19ba2460196eb..5712abc15393b61 100644 --- a/clang/test/ExtractAPI/objc_property.m +++ b/clang/test/ExtractAPI/objc_property.m @@ -177,6 +177,10 @@ @interface Interface (Category) <Protocol> { "kind": "identifier", "spelling": "myInterfaceTypeProp" + }, + { + "kind": "text", + "spelling": ";" } ], "identifier": { @@ -237,6 +241,10 @@ @interface Interface (Category) <Protocol> { "kind": "identifier", "spelling": "myInterfaceInstanceProp" + }, + { + "kind": "text", + "spelling": ";" } ], "identifier": { @@ -305,6 +313,10 @@ @interface Interface (Category) <Protocol> { "kind": "identifier", "spelling": "myCategoryTypeProp" + }, + { + "kind": "text", + "spelling": ";" } ], "identifier": { @@ -365,6 +377,10 @@ @interface Interface (Category) <Protocol> { "kind": "identifier", "spelling": "myCategoryInstanceProp" + }, + { + "kind": "text", + "spelling": ";" } ], "identifier": { @@ -483,6 +499,10 @@ @interface Interface (Category) <Protocol> { "kind": "identifier", "spelling": "myProtocolTypeProp" + }, + { + "kind": "text", + "spelling": ";" } ], "identifier": { @@ -543,6 +563,10 @@ @interface Interface (Category) <Protocol> { "kind": "identifier", "spelling": "myProtocolInstanceProp" + }, + { + "kind": "text", + "spelling": ";" } ], "identifier": { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits