forked from OSchip/llvm-project
[AST/ObjC] Make ObjCCategoryImplDecl consistent with ObjCCategoryDecl and use the category name as its DeclName
This also addresses the badness in ObjCCategoryImplDecl's API, which was hiding NamedDecl's APIs with different meaning. llvm-svn: 297131
This commit is contained in:
parent
63cfb16b93
commit
a166a2b633
|
@ -2320,11 +2320,9 @@ class ObjCImplDecl : public ObjCContainerDecl {
|
|||
protected:
|
||||
ObjCImplDecl(Kind DK, DeclContext *DC,
|
||||
ObjCInterfaceDecl *classInterface,
|
||||
IdentifierInfo *Id,
|
||||
SourceLocation nameLoc, SourceLocation atStartLoc)
|
||||
: ObjCContainerDecl(DK, DC,
|
||||
classInterface? classInterface->getIdentifier()
|
||||
: nullptr,
|
||||
nameLoc, atStartLoc),
|
||||
: ObjCContainerDecl(DK, DC, Id, nameLoc, atStartLoc),
|
||||
ClassInterface(classInterface) {}
|
||||
|
||||
public:
|
||||
|
@ -2386,9 +2384,6 @@ public:
|
|||
class ObjCCategoryImplDecl : public ObjCImplDecl {
|
||||
void anchor() override;
|
||||
|
||||
// Category name
|
||||
IdentifierInfo *Id;
|
||||
|
||||
// Category name location
|
||||
SourceLocation CategoryNameLoc;
|
||||
|
||||
|
@ -2396,8 +2391,9 @@ class ObjCCategoryImplDecl : public ObjCImplDecl {
|
|||
ObjCInterfaceDecl *classInterface,
|
||||
SourceLocation nameLoc, SourceLocation atStartLoc,
|
||||
SourceLocation CategoryNameLoc)
|
||||
: ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, nameLoc, atStartLoc),
|
||||
Id(Id), CategoryNameLoc(CategoryNameLoc) {}
|
||||
: ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, Id,
|
||||
nameLoc, atStartLoc),
|
||||
CategoryNameLoc(CategoryNameLoc) {}
|
||||
public:
|
||||
static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
IdentifierInfo *Id,
|
||||
|
@ -2407,37 +2403,10 @@ public:
|
|||
SourceLocation CategoryNameLoc);
|
||||
static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
|
||||
|
||||
/// getIdentifier - Get the identifier that names the category
|
||||
/// interface associated with this implementation.
|
||||
/// FIXME: This is a bad API, we are hiding NamedDecl::getIdentifier()
|
||||
/// with a different meaning. For example:
|
||||
/// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier()
|
||||
/// returns the class interface name, whereas
|
||||
/// ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier()
|
||||
/// returns the category name.
|
||||
IdentifierInfo *getIdentifier() const {
|
||||
return Id;
|
||||
}
|
||||
void setIdentifier(IdentifierInfo *II) { Id = II; }
|
||||
|
||||
ObjCCategoryDecl *getCategoryDecl() const;
|
||||
|
||||
SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
|
||||
|
||||
/// getName - Get the name of identifier for the class interface associated
|
||||
/// with this implementation as a StringRef.
|
||||
//
|
||||
// FIXME: This is a bad API, we are hiding NamedDecl::getName with a different
|
||||
// meaning.
|
||||
StringRef getName() const { return Id ? Id->getName() : StringRef(); }
|
||||
|
||||
/// @brief Get the name of the class associated with this interface.
|
||||
//
|
||||
// FIXME: Deprecated, move clients to getName().
|
||||
std::string getNameAsString() const {
|
||||
return getName();
|
||||
}
|
||||
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
static bool classofKind(Kind K) { return K == ObjCCategoryImpl;}
|
||||
|
||||
|
@ -2493,7 +2462,10 @@ class ObjCImplementationDecl : public ObjCImplDecl {
|
|||
SourceLocation superLoc = SourceLocation(),
|
||||
SourceLocation IvarLBraceLoc=SourceLocation(),
|
||||
SourceLocation IvarRBraceLoc=SourceLocation())
|
||||
: ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc),
|
||||
: ObjCImplDecl(ObjCImplementation, DC, classInterface,
|
||||
classInterface ? classInterface->getIdentifier()
|
||||
: nullptr,
|
||||
nameLoc, atStartLoc),
|
||||
SuperClass(superDecl), SuperLoc(superLoc), IvarLBraceLoc(IvarLBraceLoc),
|
||||
IvarRBraceLoc(IvarRBraceLoc),
|
||||
IvarInitializers(nullptr), NumIvarInitializers(0),
|
||||
|
|
|
@ -1414,6 +1414,11 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
|
|||
const PrintingPolicy &P) const {
|
||||
const DeclContext *Ctx = getDeclContext();
|
||||
|
||||
// For ObjC methods, look through categories and use the interface as context.
|
||||
if (auto *MD = dyn_cast<ObjCMethodDecl>(this))
|
||||
if (auto *ID = MD->getClassInterface())
|
||||
Ctx = ID;
|
||||
|
||||
if (Ctx->isFunctionOrMethod()) {
|
||||
printName(OS);
|
||||
return;
|
||||
|
|
|
@ -262,9 +262,13 @@ void MangleContext::mangleObjCMethodNameWithoutSize(const ObjCMethodDecl *MD,
|
|||
const ObjCContainerDecl *CD =
|
||||
dyn_cast<ObjCContainerDecl>(MD->getDeclContext());
|
||||
assert (CD && "Missing container decl in GetNameForMethod");
|
||||
OS << (MD->isInstanceMethod() ? '-' : '+') << '[' << CD->getName();
|
||||
if (const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(CD))
|
||||
OS << (MD->isInstanceMethod() ? '-' : '+') << '[';
|
||||
if (const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(CD)) {
|
||||
OS << CID->getClassInterface()->getName();
|
||||
OS << '(' << *CID << ')';
|
||||
} else {
|
||||
OS << CD->getName();
|
||||
}
|
||||
OS << ' ';
|
||||
MD->getSelector().print(OS);
|
||||
OS << ']';
|
||||
|
|
|
@ -273,8 +273,8 @@ StringRef CGDebugInfo::getObjCMethodName(const ObjCMethodDecl *OMD) {
|
|||
<< OC->getIdentifier()->getNameStart() << ')';
|
||||
}
|
||||
} else if (const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
|
||||
OS << ((const NamedDecl *)OCD)->getIdentifier()->getNameStart() << '('
|
||||
<< OCD->getIdentifier()->getNameStart() << ')';
|
||||
OS << OCD->getClassInterface()->getName() << '('
|
||||
<< OCD->getName() << ')';
|
||||
} else if (isa<ObjCProtocolDecl>(DC)) {
|
||||
// We can extract the type of the class from the self pointer.
|
||||
if (ImplicitParamDecl *SelfDecl = OMD->getSelfDecl()) {
|
||||
|
|
|
@ -1138,7 +1138,6 @@ void ASTDeclReader::VisitObjCImplDecl(ObjCImplDecl *D) {
|
|||
|
||||
void ASTDeclReader::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
|
||||
VisitObjCImplDecl(D);
|
||||
D->setIdentifier(Record.getIdentifierInfo());
|
||||
D->CategoryNameLoc = ReadSourceLocation();
|
||||
}
|
||||
|
||||
|
|
|
@ -814,7 +814,6 @@ void ASTDeclWriter::VisitObjCImplDecl(ObjCImplDecl *D) {
|
|||
|
||||
void ASTDeclWriter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
|
||||
VisitObjCImplDecl(D);
|
||||
Record.AddIdentifierRef(D->getIdentifier());
|
||||
Record.AddSourceLocation(D->getCategoryNameLoc());
|
||||
Code = serialization::DECL_OBJC_CATEGORY_IMPL;
|
||||
}
|
||||
|
|
|
@ -615,8 +615,8 @@ std::string AnalysisConsumer::getFunctionName(const Decl *D) {
|
|||
<< OC->getIdentifier()->getNameStart() << ')';
|
||||
}
|
||||
} else if (const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
|
||||
OS << ((const NamedDecl *)OCD)->getIdentifier()->getNameStart() << '('
|
||||
<< OCD->getIdentifier()->getNameStart() << ')';
|
||||
OS << OCD->getClassInterface()->getName() << '('
|
||||
<< OCD->getName() << ')';
|
||||
} else if (isa<ObjCProtocolDecl>(DC)) {
|
||||
// We can extract the type of the class from the self pointer.
|
||||
if (ImplicitParamDecl *SelfDecl = OMD->getSelfDecl()) {
|
||||
|
|
|
@ -188,7 +188,7 @@ extern int setjmp(jmp_buf);
|
|||
@end
|
||||
|
||||
// CHECK: [[@LINE+2]]:17 | class/ObjC | I3 | c:objc(cs)I3 | _OBJC_CLASS_$_I3 | Ref,RelCont | rel: 1
|
||||
// CHECK: [[@LINE+1]]:20 | extension/ObjC | I3 | c:objc(cy)I3@bar | <no-cgname> | Def | rel: 0
|
||||
// CHECK: [[@LINE+1]]:20 | extension/ObjC | bar | c:objc(cy)I3@bar | <no-cgname> | Def | rel: 0
|
||||
@implementation I3(bar)
|
||||
@end
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
@interface MyTestCase(cat)
|
||||
@end
|
||||
// CHECK: [[@LINE+2]]:17 | class(test)/ObjC | MyTestCase | c:objc(cs)MyTestCase | _OBJC_CLASS_$_MyTestCase | Ref,RelCont | rel: 1
|
||||
// CHECK: [[@LINE+1]]:28 | extension/ObjC | MyTestCase | c:objc(cy)MyTestCase@cat | <no-cgname> | Def | rel: 0
|
||||
// CHECK: [[@LINE+1]]:28 | extension/ObjC | cat | c:objc(cy)MyTestCase@cat | <no-cgname> | Def | rel: 0
|
||||
@implementation MyTestCase(cat)
|
||||
// CHECK: [[@LINE+1]]:9 | instance-method(test)/ObjC | testInCat | c:objc(cs)MyTestCase(im)testInCat | -[MyTestCase(cat) testInCat] | Def,Dyn,RelChild | rel: 1
|
||||
- (void)testInCat {}
|
||||
|
|
|
@ -77,7 +77,7 @@
|
|||
@end
|
||||
// CHECK: ObjCCategoryDecl{{.*}} TestObjCCategoryDecl
|
||||
// CHECK-NEXT: ObjCInterface{{.*}} 'TestObjCClass'
|
||||
// CHECK-NEXT: ObjCCategoryImpl{{.*}} 'TestObjCClass'
|
||||
// CHECK-NEXT: ObjCCategoryImpl{{.*}} 'TestObjCCategoryDecl'
|
||||
// CHECK-NEXT: ObjCProtocol{{.*}} 'P'
|
||||
// CHECK-NEXT: ObjCMethodDecl{{.*}} bar
|
||||
|
||||
|
@ -85,7 +85,7 @@
|
|||
- (void) bar {
|
||||
}
|
||||
@end
|
||||
// CHECK: ObjCCategoryImplDecl{{.*}} TestObjCClass
|
||||
// CHECK: ObjCCategoryImplDecl{{.*}} TestObjCCategoryDecl
|
||||
// CHECK-NEXT: ObjCInterface{{.*}} 'TestObjCClass'
|
||||
// CHECK-NEXT: ObjCCategory{{.*}} 'TestObjCCategoryDecl'
|
||||
// CHECK-NEXT: ObjCMethodDecl{{.*}} bar
|
||||
|
|
Loading…
Reference in New Issue