зеркало из https://github.com/microsoft/clang-1.git
Speculatively revert r110610 " Make ObjCInterfaceDecl redeclarable,
and create separate decl nodes for forward declarations and the definition," which appears to be causing significant Objective-C breakage. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110803 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
018220c343
Коммит
deacbdca55
|
@ -49,11 +49,6 @@ public:
|
|||
/// elements). Use Decl::getNextDeclarator() to walk the chain.
|
||||
virtual void HandleTopLevelDecl(DeclGroupRef D);
|
||||
|
||||
/// HandleInterestingDecl - Handle the specified interesting declaration. This
|
||||
/// is called by the PCH reader when deserializing things that might interest
|
||||
/// the consumer. The default implementation forwards to HandleTopLevelDecl.
|
||||
virtual void HandleInterestingDecl(DeclGroupRef D);
|
||||
|
||||
/// HandleTranslationUnit - This method is called when the ASTs for entire
|
||||
/// translation unit have been parsed.
|
||||
virtual void HandleTranslationUnit(ASTContext &Ctx) {}
|
||||
|
|
|
@ -668,10 +668,7 @@ public:
|
|||
unsigned NumArgs,
|
||||
const TemplateArgument *Args);
|
||||
|
||||
/// getObjCInterfaceType - Return the unique reference to the type for the
|
||||
/// specified ObjC interface decl.
|
||||
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
|
||||
const ObjCInterfaceDecl *PrevDecl = 0);
|
||||
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl);
|
||||
|
||||
QualType getObjCObjectType(QualType Base,
|
||||
ObjCProtocolDecl * const *Protocols,
|
||||
|
|
|
@ -450,10 +450,7 @@ public:
|
|||
/// Unlike C++, ObjC is a single-rooted class model. In Cocoa, classes
|
||||
/// typically inherit from NSObject (an exception is NSProxy).
|
||||
///
|
||||
class ObjCInterfaceDecl : public ObjCContainerDecl,
|
||||
public Redeclarable<ObjCInterfaceDecl> {
|
||||
typedef Redeclarable<ObjCInterfaceDecl> redeclarable_base;
|
||||
|
||||
class ObjCInterfaceDecl : public ObjCContainerDecl {
|
||||
/// TypeForDecl - This indicates the Type object that represents this
|
||||
/// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType
|
||||
mutable Type *TypeForDecl;
|
||||
|
@ -477,52 +474,15 @@ class ObjCInterfaceDecl : public ObjCContainerDecl,
|
|||
SourceLocation EndLoc; // marks the '>', '}', or identifier.
|
||||
|
||||
ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
|
||||
SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
|
||||
bool FD, bool isInternal);
|
||||
|
||||
protected:
|
||||
virtual ObjCInterfaceDecl *getNextRedeclaration() {
|
||||
return RedeclLink.getNext();
|
||||
}
|
||||
SourceLocation CLoc, bool FD, bool isInternal);
|
||||
|
||||
public:
|
||||
typedef redeclarable_base::redecl_iterator redecl_iterator;
|
||||
redecl_iterator redecls_begin() const {
|
||||
return redeclarable_base::redecls_begin();
|
||||
}
|
||||
redecl_iterator redecls_end() const {
|
||||
return redeclarable_base::redecls_end();
|
||||
}
|
||||
|
||||
static ObjCInterfaceDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation atLoc,
|
||||
IdentifierInfo *Id,
|
||||
SourceLocation ClassLoc,
|
||||
ObjCInterfaceDecl *PrevDecl,
|
||||
SourceLocation ClassLoc = SourceLocation(),
|
||||
bool ForwardDecl = false,
|
||||
bool isInternal = false);
|
||||
|
||||
static ObjCInterfaceDecl *Create(ASTContext &C, EmptyShell Empty);
|
||||
|
||||
void setPreviousDeclaration(ObjCInterfaceDecl *Prev) {
|
||||
// Adopt a type pointer if it exists.
|
||||
TypeForDecl = Prev->TypeForDecl;
|
||||
redeclarable_base::setPreviousDeclaration(Prev);
|
||||
}
|
||||
|
||||
virtual ObjCInterfaceDecl *getCanonicalDecl() {
|
||||
return getFirstDeclaration();
|
||||
}
|
||||
const ObjCInterfaceDecl *getCanonicalDecl() const {
|
||||
return const_cast<ObjCInterfaceDecl*>(this)->getCanonicalDecl();
|
||||
}
|
||||
|
||||
/// Get the interface declaration that is a definition, if there is one.
|
||||
ObjCInterfaceDecl *getDefinition();
|
||||
const ObjCInterfaceDecl *getDefinition() const {
|
||||
return const_cast<ObjCInterfaceDecl*>(this)->getDefinition();
|
||||
}
|
||||
|
||||
const ObjCProtocolList &getReferencedProtocols() const {
|
||||
return ReferencedProtocols;
|
||||
}
|
||||
|
@ -575,7 +535,6 @@ public:
|
|||
ASTContext &C);
|
||||
|
||||
bool isForwardDecl() const { return ForwardDecl; }
|
||||
bool isDefinition() const { return !ForwardDecl; }
|
||||
void setForwardDecl(bool val) { ForwardDecl = val; }
|
||||
|
||||
ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
|
||||
|
|
|
@ -3038,7 +3038,7 @@ class ObjCInterfaceType : public ObjCObjectType {
|
|||
friend class ASTContext; // ASTContext creates these.
|
||||
public:
|
||||
/// getDecl - Get the declaration of this interface.
|
||||
ObjCInterfaceDecl *getDecl() const;
|
||||
ObjCInterfaceDecl *getDecl() const { return Decl; }
|
||||
|
||||
bool isSugared() const { return false; }
|
||||
QualType desugar() const { return QualType(this, 0); }
|
||||
|
|
|
@ -17,6 +17,3 @@ using namespace clang;
|
|||
|
||||
void ASTConsumer::HandleTopLevelDecl(DeclGroupRef D) {}
|
||||
|
||||
void ASTConsumer::HandleInterestingDecl(DeclGroupRef D) {
|
||||
HandleTopLevelDecl(D);
|
||||
}
|
||||
|
|
|
@ -872,7 +872,7 @@ void ASTContext::ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
|
|||
/// CollectNonClassIvars -
|
||||
/// This routine collects all other ivars which are not declared in the class.
|
||||
/// This includes synthesized ivars (via @synthesize) and those in
|
||||
/// class's @implementation.
|
||||
// class's @implementation.
|
||||
///
|
||||
void ASTContext::CollectNonClassIvars(const ObjCInterfaceDecl *OI,
|
||||
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
|
||||
|
@ -2212,24 +2212,18 @@ QualType ASTContext::getObjCObjectPointerType(QualType ObjectT) {
|
|||
return QualType(QType, 0);
|
||||
}
|
||||
|
||||
QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
|
||||
const ObjCInterfaceDecl *PrevDecl) {
|
||||
assert(Decl && "Passed null for Decl param");
|
||||
/// getObjCInterfaceType - Return the unique reference to the type for the
|
||||
/// specified ObjC interface decl. The list of protocols is optional.
|
||||
QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl) {
|
||||
if (Decl->TypeForDecl)
|
||||
return QualType(Decl->TypeForDecl, 0);
|
||||
|
||||
if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
|
||||
|
||||
if (PrevDecl) {
|
||||
assert(PrevDecl->TypeForDecl && "previous decl has no TypeForDecl");
|
||||
Decl->TypeForDecl = PrevDecl->TypeForDecl;
|
||||
return QualType(PrevDecl->TypeForDecl, 0);
|
||||
}
|
||||
|
||||
assert(!Decl->getPreviousDeclaration() &&
|
||||
"interface has previous declaration");
|
||||
|
||||
Decl->TypeForDecl = new (*this, TypeAlignment) ObjCInterfaceType(Decl);
|
||||
Types.push_back(Decl->TypeForDecl);
|
||||
return QualType(Decl->TypeForDecl, 0);
|
||||
// FIXME: redeclarations?
|
||||
void *Mem = Allocate(sizeof(ObjCInterfaceType), TypeAlignment);
|
||||
ObjCInterfaceType *T = new (Mem) ObjCInterfaceType(Decl);
|
||||
Decl->TypeForDecl = T;
|
||||
Types.push_back(T);
|
||||
return QualType(T, 0);
|
||||
}
|
||||
|
||||
/// getTypeOfExprType - Unlike many "get<Type>" functions, we can't unique
|
||||
|
|
|
@ -2467,18 +2467,6 @@ Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
|
|||
}
|
||||
|
||||
Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
|
||||
// If this interface has a definition in the translation unit we're coming
|
||||
// from, but this particular declaration is not that definition, import the
|
||||
// definition and map to that.
|
||||
ObjCInterfaceDecl *Definition = D->getDefinition();
|
||||
if (Definition && Definition != D) {
|
||||
Decl *ImportedDef = Importer.Import(Definition);
|
||||
if (!ImportedDef)
|
||||
return 0;
|
||||
|
||||
return Importer.Imported(D, ImportedDef);
|
||||
}
|
||||
|
||||
// Import the major distinguishing characteristics of an @interface.
|
||||
DeclContext *DC, *LexicalDC;
|
||||
DeclarationName Name;
|
||||
|
@ -2503,7 +2491,7 @@ Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
|
|||
ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(),
|
||||
DC, Loc,
|
||||
Name.getAsIdentifierInfo(),
|
||||
Importer.Import(D->getClassLoc()), 0,
|
||||
Importer.Import(D->getClassLoc()),
|
||||
D->isForwardDecl(),
|
||||
D->isImplicitInterfaceDecl());
|
||||
ToIface->setForwardDecl(D->isForwardDecl());
|
||||
|
|
|
@ -45,14 +45,6 @@ void ObjCProtocolList::set(ObjCProtocolDecl* const* InList, unsigned Elts,
|
|||
// ObjCInterfaceDecl
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
ObjCInterfaceDecl *ObjCInterfaceDecl::getDefinition() {
|
||||
for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
|
||||
if (I->isDefinition())
|
||||
return *I;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// getIvarDecl - This method looks up an ivar in this ContextDecl.
|
||||
///
|
||||
ObjCIvarDecl *
|
||||
|
@ -440,30 +432,18 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C,
|
|||
SourceLocation atLoc,
|
||||
IdentifierInfo *Id,
|
||||
SourceLocation ClassLoc,
|
||||
ObjCInterfaceDecl *PrevDecl,
|
||||
bool ForwardDecl, bool isInternal){
|
||||
ObjCInterfaceDecl *D = new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc,
|
||||
PrevDecl, ForwardDecl,
|
||||
isInternal);
|
||||
C.getObjCInterfaceType(D, PrevDecl);
|
||||
return D;
|
||||
}
|
||||
|
||||
ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C, EmptyShell) {
|
||||
return new (C) ObjCInterfaceDecl(0, SourceLocation(), 0, SourceLocation(),
|
||||
0, false, false);
|
||||
return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl,
|
||||
isInternal);
|
||||
}
|
||||
|
||||
ObjCInterfaceDecl::
|
||||
ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
|
||||
SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
|
||||
bool FD, bool isInternal)
|
||||
SourceLocation CLoc, bool FD, bool isInternal)
|
||||
: ObjCContainerDecl(ObjCInterface, DC, atLoc, Id),
|
||||
TypeForDecl(0), SuperClass(0),
|
||||
CategoryList(0), ForwardDecl(FD), InternalInterface(isInternal),
|
||||
ClassLoc(CLoc) {
|
||||
if (PrevDecl)
|
||||
setPreviousDeclaration(PrevDecl);
|
||||
}
|
||||
|
||||
ObjCImplementationDecl *ObjCInterfaceDecl::getImplementation() const {
|
||||
|
|
|
@ -727,19 +727,12 @@ void DeclPrinter::VisitObjCImplementationDecl(ObjCImplementationDecl *OID) {
|
|||
|
||||
void DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) {
|
||||
std::string I = OID->getNameAsString();
|
||||
|
||||
if (OID->isForwardDecl()) {
|
||||
// These shouldn't be directly visited, but in case they are, write them
|
||||
// as an @class declaration.
|
||||
Out << "@class " << I;
|
||||
return;
|
||||
}
|
||||
|
||||
ObjCInterfaceDecl *SID = OID->getSuperClass();
|
||||
|
||||
Out << "@interface " << I;
|
||||
if (SID)
|
||||
Out << " : " << SID;
|
||||
Out << "@interface " << I << " : " << SID;
|
||||
else
|
||||
Out << "@interface " << I;
|
||||
|
||||
// Protocols?
|
||||
const ObjCList<ObjCProtocolDecl> &Protocols = OID->getReferencedProtocols();
|
||||
|
|
|
@ -360,17 +360,6 @@ const ObjCObjectPointerType *Type::getAsObjCInterfacePointerType() const {
|
|||
return 0;
|
||||
}
|
||||
|
||||
ObjCInterfaceDecl *ObjCInterfaceType::getDecl() const {
|
||||
for (ObjCInterfaceDecl::redecl_iterator I = Decl->redecls_begin(),
|
||||
E = Decl->redecls_end();
|
||||
I != E; ++I) {
|
||||
if (I->isDefinition())
|
||||
return *I;
|
||||
}
|
||||
// If we can't find a definition, return whatever we have.
|
||||
return Decl;
|
||||
}
|
||||
|
||||
const CXXRecordDecl *Type::getCXXRecordDeclForPointerType() const {
|
||||
if (const PointerType *PT = getAs<PointerType>())
|
||||
if (const RecordType *RT = PT->getPointeeType()->getAs<RecordType>())
|
||||
|
|
|
@ -320,9 +320,6 @@ public:
|
|||
Unit.addTopLevelDecl(D);
|
||||
}
|
||||
}
|
||||
|
||||
// We're not interested in "interesting" decls.
|
||||
void HandleInterestingDecl(DeclGroupRef) {}
|
||||
};
|
||||
|
||||
class TopLevelDeclTrackerAction : public ASTFrontendAction {
|
||||
|
|
|
@ -2262,7 +2262,7 @@ QualType PCHReader::ReadTypeRecord(unsigned Index) {
|
|||
SavedStreamPosition SavedPosition(DeclsCursor);
|
||||
|
||||
ReadingKindTracker ReadingKind(Read_Type, *this);
|
||||
|
||||
|
||||
// Note that we are loading a type record.
|
||||
Deserializing AType(this);
|
||||
|
||||
|
@ -3027,7 +3027,7 @@ void PCHReader::PassInterestingDeclsToConsumer() {
|
|||
while (!InterestingDecls.empty()) {
|
||||
DeclGroupRef DG(InterestingDecls.front());
|
||||
InterestingDecls.pop_front();
|
||||
Consumer->HandleInterestingDecl(DG);
|
||||
Consumer->HandleTopLevelDecl(DG);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace clang {
|
|||
const pch::DeclID ThisDeclID;
|
||||
const PCHReader::RecordData &Record;
|
||||
unsigned &Idx;
|
||||
pch::TypeID TypeIDForDecl;
|
||||
pch::TypeID TypeIDForTypeDecl;
|
||||
|
||||
uint64_t GetCurrentCursorOffset();
|
||||
|
||||
|
@ -43,7 +43,7 @@ namespace clang {
|
|||
pch::DeclID thisDeclID, const PCHReader::RecordData &Record,
|
||||
unsigned &Idx)
|
||||
: Reader(Reader), Cursor(Cursor), ThisDeclID(thisDeclID), Record(Record),
|
||||
Idx(Idx), TypeIDForDecl(0) { }
|
||||
Idx(Idx), TypeIDForTypeDecl(0) { }
|
||||
|
||||
void Visit(Decl *D);
|
||||
|
||||
|
@ -132,11 +132,9 @@ uint64_t PCHDeclReader::GetCurrentCursorOffset() {
|
|||
void PCHDeclReader::Visit(Decl *D) {
|
||||
DeclVisitor<PCHDeclReader, void>::Visit(D);
|
||||
|
||||
// if we have a fully initialized Decl, we can safely read its type now.
|
||||
if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) {
|
||||
TD->setTypeForDecl(Reader.GetType(TypeIDForDecl).getTypePtr());
|
||||
} else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
|
||||
ID->setTypeForDecl(Reader.GetType(TypeIDForDecl).getTypePtr());
|
||||
// if we have a fully initialized TypeDecl, we can safely read its type now.
|
||||
TD->setTypeForDecl(Reader.GetType(TypeIDForTypeDecl).getTypePtr());
|
||||
} else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
// FunctionDecl's body was written last after all other Stmts/Exprs.
|
||||
if (Record[Idx++])
|
||||
|
@ -172,7 +170,7 @@ void PCHDeclReader::VisitNamedDecl(NamedDecl *ND) {
|
|||
void PCHDeclReader::VisitTypeDecl(TypeDecl *TD) {
|
||||
VisitNamedDecl(TD);
|
||||
// Delay type reading until after we have fully initialized the decl.
|
||||
TypeIDForDecl = Record[Idx++];
|
||||
TypeIDForTypeDecl = Record[Idx++];
|
||||
}
|
||||
|
||||
void PCHDeclReader::VisitTypedefDecl(TypedefDecl *TD) {
|
||||
|
@ -369,11 +367,7 @@ void PCHDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) {
|
|||
|
||||
void PCHDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
|
||||
VisitObjCContainerDecl(ID);
|
||||
ID->setForwardDecl(Record[Idx++]);
|
||||
ID->setImplicitInterfaceDecl(Record[Idx++]);
|
||||
VisitRedeclarable(ID);
|
||||
// Must delay type reading until the redecl chain is complete.
|
||||
TypeIDForDecl = Record[Idx++];
|
||||
ID->setTypeForDecl(Reader.GetType(Record[Idx++]).getTypePtr());
|
||||
ID->setSuperClass(cast_or_null<ObjCInterfaceDecl>
|
||||
(Reader.GetDecl(Record[Idx++])));
|
||||
unsigned NumProtocols = Record[Idx++];
|
||||
|
@ -394,6 +388,8 @@ void PCHDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
|
|||
IVars.push_back(cast<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])));
|
||||
ID->setCategoryList(
|
||||
cast_or_null<ObjCCategoryDecl>(Reader.GetDecl(Record[Idx++])));
|
||||
ID->setForwardDecl(Record[Idx++]);
|
||||
ID->setImplicitInterfaceDecl(Record[Idx++]);
|
||||
ID->setClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
|
||||
ID->setSuperClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
|
||||
ID->setLocEnd(SourceLocation::getFromRawEncoding(Record[Idx++]));
|
||||
|
@ -1463,7 +1459,7 @@ Decl *PCHReader::ReadDeclRecord(unsigned Index, pch::DeclID ID) {
|
|||
Selector(), QualType(), 0, 0);
|
||||
break;
|
||||
case pch::DECL_OBJC_INTERFACE:
|
||||
D = ObjCInterfaceDecl::Create(*Context, Decl::EmptyShell());
|
||||
D = ObjCInterfaceDecl::Create(*Context, 0, SourceLocation(), 0);
|
||||
break;
|
||||
case pch::DECL_OBJC_IVAR:
|
||||
D = ObjCIvarDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), 0,
|
||||
|
|
|
@ -305,9 +305,7 @@ void PCHTypeWriter::VisitInjectedClassNameType(const InjectedClassNameType *T) {
|
|||
}
|
||||
|
||||
void PCHTypeWriter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
|
||||
// The stored declaration must be the first, but getDecl() returns the
|
||||
// definition.
|
||||
Writer.AddDeclRef(T->getDecl()->getFirstDeclaration(), Record);
|
||||
Writer.AddDeclRef(T->getDecl(), Record);
|
||||
Code = pch::TYPE_OBJC_INTERFACE;
|
||||
}
|
||||
|
||||
|
|
|
@ -340,9 +340,6 @@ void PCHDeclWriter::VisitObjCContainerDecl(ObjCContainerDecl *D) {
|
|||
|
||||
void PCHDeclWriter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
|
||||
VisitObjCContainerDecl(D);
|
||||
Record.push_back(D->isForwardDecl());
|
||||
Record.push_back(D->isImplicitInterfaceDecl());
|
||||
VisitRedeclarable(D);
|
||||
Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record);
|
||||
Writer.AddDeclRef(D->getSuperClass(), Record);
|
||||
Record.push_back(D->protocol_size());
|
||||
|
@ -359,6 +356,8 @@ void PCHDeclWriter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
|
|||
IEnd = D->ivar_end(); I != IEnd; ++I)
|
||||
Writer.AddDeclRef(*I, Record);
|
||||
Writer.AddDeclRef(D->getCategoryList(), Record);
|
||||
Record.push_back(D->isForwardDecl());
|
||||
Record.push_back(D->isImplicitInterfaceDecl());
|
||||
Writer.AddSourceLocation(D->getClassLoc(), Record);
|
||||
Writer.AddSourceLocation(D->getSuperClassLoc(), Record);
|
||||
Writer.AddSourceLocation(D->getLocEnd(), Record);
|
||||
|
|
|
@ -89,7 +89,7 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
|
|||
ObjCInterfaceDecl *ProtocolDecl =
|
||||
ObjCInterfaceDecl::Create(Context, CurContext, SourceLocation(),
|
||||
&Context.Idents.get("Protocol"),
|
||||
SourceLocation(), 0, true);
|
||||
SourceLocation(), true);
|
||||
Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl));
|
||||
PushOnScopeChains(ProtocolDecl, TUScope, false);
|
||||
}
|
||||
|
|
|
@ -3748,28 +3748,20 @@ static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
|
|||
for (DeclContext::decl_iterator D = Ctx->decls_begin(),
|
||||
DEnd = Ctx->decls_end();
|
||||
D != DEnd; ++D) {
|
||||
// Record any interfaces we find. Forward declarations are never registered
|
||||
// in the lexical contest, so if we're only looking for those, don't bother.
|
||||
if (!OnlyForwardDeclarations)
|
||||
if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
|
||||
if (!OnlyUnimplemented || !Class->getImplementation())
|
||||
Results.AddResult(Result(Class, 0), CurContext, 0, false);
|
||||
// Record any interfaces we find.
|
||||
if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
|
||||
if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
|
||||
(!OnlyUnimplemented || !Class->getImplementation()))
|
||||
Results.AddResult(Result(Class, 0), CurContext, 0, false);
|
||||
|
||||
// Record any forward-declared interfaces we find.
|
||||
if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
|
||||
for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
|
||||
C != CEnd; ++C) {
|
||||
ObjCInterfaceDecl *IDecl = C->getInterface();
|
||||
ObjCInterfaceDecl *IDef = IDecl->getDefinition();
|
||||
// If there's a definition, and we're looking for everything, then we
|
||||
// already added the decl in question above.
|
||||
if (!OnlyForwardDeclarations && !OnlyUnimplemented && IDef)
|
||||
continue;
|
||||
if ((!OnlyForwardDeclarations || !IDef) &&
|
||||
(!OnlyUnimplemented || !IDef || !IDef->getImplementation()))
|
||||
Results.AddResult(Result(IDecl, 0), CurContext,
|
||||
C != CEnd; ++C)
|
||||
if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
|
||||
(!OnlyUnimplemented || !C->getInterface()->getImplementation()))
|
||||
Results.AddResult(Result(C->getInterface(), 0), CurContext,
|
||||
0, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -606,6 +606,45 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
|
|||
}
|
||||
}
|
||||
|
||||
/// \brief Look for an Objective-C class in the translation unit.
|
||||
///
|
||||
/// \param Id The name of the Objective-C class we're looking for. If
|
||||
/// typo-correction fixes this name, the Id will be updated
|
||||
/// to the fixed name.
|
||||
///
|
||||
/// \param IdLoc The location of the name in the translation unit.
|
||||
///
|
||||
/// \param TypoCorrection If true, this routine will attempt typo correction
|
||||
/// if there is no class with the given name.
|
||||
///
|
||||
/// \returns The declaration of the named Objective-C class, or NULL if the
|
||||
/// class could not be found.
|
||||
ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *&Id,
|
||||
SourceLocation IdLoc,
|
||||
bool TypoCorrection) {
|
||||
// The third "scope" argument is 0 since we aren't enabling lazy built-in
|
||||
// creation from this context.
|
||||
NamedDecl *IDecl = LookupSingleName(TUScope, Id, IdLoc, LookupOrdinaryName);
|
||||
|
||||
if (!IDecl && TypoCorrection) {
|
||||
// Perform typo correction at the given location, but only if we
|
||||
// find an Objective-C class name.
|
||||
LookupResult R(*this, Id, IdLoc, LookupOrdinaryName);
|
||||
if (CorrectTypo(R, TUScope, 0, 0, false, CTC_NoKeywords) &&
|
||||
(IDecl = R.getAsSingle<ObjCInterfaceDecl>())) {
|
||||
Diag(IdLoc, diag::err_undef_interface_suggest)
|
||||
<< Id << IDecl->getDeclName()
|
||||
<< FixItHint::CreateReplacement(IdLoc, IDecl->getNameAsString());
|
||||
Diag(IDecl->getLocation(), diag::note_previous_decl)
|
||||
<< IDecl->getDeclName();
|
||||
|
||||
Id = IDecl->getIdentifier();
|
||||
}
|
||||
}
|
||||
|
||||
return dyn_cast_or_null<ObjCInterfaceDecl>(IDecl);
|
||||
}
|
||||
|
||||
/// getNonFieldDeclScope - Retrieves the innermost scope, starting
|
||||
/// from S, where a non-field would be declared. This routine copes
|
||||
/// with the difference between C and C++ scoping rules in structs and
|
||||
|
|
|
@ -20,50 +20,6 @@
|
|||
#include "clang/Parse/DeclSpec.h"
|
||||
using namespace clang;
|
||||
|
||||
/// \brief Look for an Objective-C class in the translation unit.
|
||||
///
|
||||
/// \param Id The name of the Objective-C class we're looking for. If
|
||||
/// typo-correction fixes this name, the Id will be updated
|
||||
/// to the fixed name.
|
||||
///
|
||||
/// \param IdLoc The location of the name in the translation unit.
|
||||
///
|
||||
/// \param TypoCorrection If true, this routine will attempt typo correction
|
||||
/// if there is no class with the given name.
|
||||
///
|
||||
/// \returns The declaration of the named Objective-C class, which is also the
|
||||
/// definition if one is available, or NULL if the class could not be found.
|
||||
ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *&Id,
|
||||
SourceLocation IdLoc,
|
||||
bool TypoCorrection) {
|
||||
// The third "scope" argument is 0 since we aren't enabling lazy built-in
|
||||
// creation from this context.
|
||||
NamedDecl *Decl = LookupSingleName(TUScope, Id, IdLoc, LookupOrdinaryName);
|
||||
|
||||
if (!Decl && TypoCorrection) {
|
||||
// Perform typo correction at the given location, but only if we
|
||||
// find an Objective-C class name.
|
||||
LookupResult R(*this, Id, IdLoc, LookupOrdinaryName);
|
||||
if (CorrectTypo(R, TUScope, 0, 0, false, CTC_NoKeywords) &&
|
||||
(Decl = R.getAsSingle<ObjCInterfaceDecl>())) {
|
||||
Diag(IdLoc, diag::err_undef_interface_suggest)
|
||||
<< Id << Decl->getDeclName()
|
||||
<< FixItHint::CreateReplacement(IdLoc, Decl->getNameAsString());
|
||||
Diag(Decl->getLocation(), diag::note_previous_decl)
|
||||
<< Decl->getDeclName();
|
||||
|
||||
Id = Decl->getIdentifier();
|
||||
}
|
||||
}
|
||||
|
||||
ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(Decl);
|
||||
if (IDecl) {
|
||||
if (ObjCInterfaceDecl *Def = IDecl->getDefinition())
|
||||
IDecl = Def;
|
||||
}
|
||||
return IDecl;
|
||||
}
|
||||
|
||||
/// ActOnStartOfObjCMethodDef - This routine sets up parameters; invisible
|
||||
/// and user declared, in the method definition's AST.
|
||||
void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, DeclPtrTy D) {
|
||||
|
@ -109,8 +65,6 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
|
|||
SourceLocation EndProtoLoc, AttributeList *AttrList) {
|
||||
assert(ClassName && "Missing class identifier");
|
||||
|
||||
bool Invalid = false;
|
||||
|
||||
// Check for another declaration kind with the same name.
|
||||
NamedDecl *PrevDecl = LookupSingleName(TUScope, ClassName, ClassLoc,
|
||||
LookupOrdinaryName, ForRedeclaration);
|
||||
|
@ -118,35 +72,42 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
|
|||
if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
|
||||
Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
|
||||
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
|
||||
// Set the new decl invalid and ignore the old.
|
||||
Invalid = true;
|
||||
PrevDecl = 0;
|
||||
}
|
||||
|
||||
ObjCInterfaceDecl *ODecl = cast_or_null<ObjCInterfaceDecl>(PrevDecl);
|
||||
if (ODecl) {
|
||||
ObjCInterfaceDecl* IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
|
||||
if (IDecl) {
|
||||
// Class already seen. Is it a forward declaration?
|
||||
if (ObjCInterfaceDecl *Def = ODecl->getDefinition()) {
|
||||
Invalid = true;
|
||||
Diag(AtInterfaceLoc, diag::err_duplicate_class_def) << Def->getDeclName();
|
||||
Diag(Def->getLocation(), diag::note_previous_definition);
|
||||
if (!IDecl->isForwardDecl()) {
|
||||
IDecl->setInvalidDecl();
|
||||
Diag(AtInterfaceLoc, diag::err_duplicate_class_def)<<IDecl->getDeclName();
|
||||
Diag(IDecl->getLocation(), diag::note_previous_definition);
|
||||
|
||||
// Return the previous class interface and ignore the new one.
|
||||
return DeclPtrTy::make(ODecl);
|
||||
// Return the previous class interface.
|
||||
// FIXME: don't leak the objects passed in!
|
||||
return DeclPtrTy::make(IDecl);
|
||||
} else {
|
||||
IDecl->setLocation(AtInterfaceLoc);
|
||||
IDecl->setForwardDecl(false);
|
||||
IDecl->setClassLoc(ClassLoc);
|
||||
|
||||
// Since this ObjCInterfaceDecl was created by a forward declaration,
|
||||
// we now add it to the DeclContext since it wasn't added before
|
||||
// (see ActOnForwardClassDeclaration).
|
||||
IDecl->setLexicalDeclContext(CurContext);
|
||||
CurContext->addDecl(IDecl);
|
||||
|
||||
if (AttrList)
|
||||
ProcessDeclAttributeList(TUScope, IDecl, AttrList);
|
||||
}
|
||||
} else {
|
||||
IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc,
|
||||
ClassName, ClassLoc);
|
||||
if (AttrList)
|
||||
ProcessDeclAttributeList(TUScope, IDecl, AttrList);
|
||||
|
||||
PushOnScopeChains(IDecl, TUScope);
|
||||
}
|
||||
|
||||
ObjCInterfaceDecl *IDecl =
|
||||
ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc,
|
||||
ClassName, ClassLoc, ODecl);
|
||||
if (Invalid)
|
||||
IDecl->setInvalidDecl();
|
||||
|
||||
if (AttrList)
|
||||
ProcessDeclAttributeList(TUScope, IDecl, AttrList);
|
||||
|
||||
PushOnScopeChains(IDecl, TUScope);
|
||||
|
||||
if (SuperName) {
|
||||
// Check if a different kind of symbol declared in this scope.
|
||||
PrevDecl = LookupSingleName(TUScope, SuperName, SuperLoc,
|
||||
|
@ -164,8 +125,6 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
|
|||
}
|
||||
}
|
||||
|
||||
// Since we just pushed IDecl on the scope chain, if PrevDecl is the same
|
||||
// class, it will be the same declaration.
|
||||
if (PrevDecl == IDecl) {
|
||||
Diag(SuperLoc, diag::err_recursive_superclass)
|
||||
<< SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
|
||||
|
@ -181,11 +140,11 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
|
|||
if (PrevDecl && SuperClassDecl == 0) {
|
||||
// The previous declaration was not a class decl. Check if we have a
|
||||
// typedef. If we do, get the underlying class type.
|
||||
if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(PrevDecl)){
|
||||
if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
|
||||
QualType T = TDecl->getUnderlyingType();
|
||||
if (T->isObjCObjectType()) {
|
||||
if (NamedDecl *NDecl = T->getAs<ObjCObjectType>()->getInterface())
|
||||
SuperClassDecl = dyn_cast<ObjCInterfaceDecl>(NDecl);
|
||||
if (NamedDecl *IDecl = T->getAs<ObjCObjectType>()->getInterface())
|
||||
SuperClassDecl = dyn_cast<ObjCInterfaceDecl>(IDecl);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,11 +159,6 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
|
|||
}
|
||||
}
|
||||
|
||||
if (SuperClassDecl) {
|
||||
if (ObjCInterfaceDecl *Def = SuperClassDecl->getDefinition())
|
||||
SuperClassDecl = Def;
|
||||
}
|
||||
|
||||
if (!dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
|
||||
if (!SuperClassDecl)
|
||||
Diag(SuperLoc, diag::err_undef_superclass)
|
||||
|
@ -576,7 +530,7 @@ Sema::DeclPtrTy Sema::ActOnStartClassImplementation(
|
|||
IdentifierInfo *ClassName, SourceLocation ClassLoc,
|
||||
IdentifierInfo *SuperClassname,
|
||||
SourceLocation SuperClassLoc) {
|
||||
ObjCInterfaceDecl *IDecl = 0, *ODecl = 0;
|
||||
ObjCInterfaceDecl* IDecl = 0;
|
||||
// Check for another declaration kind with the same name.
|
||||
NamedDecl *PrevDecl
|
||||
= LookupSingleName(TUScope, ClassName, ClassLoc, LookupOrdinaryName,
|
||||
|
@ -584,10 +538,11 @@ Sema::DeclPtrTy Sema::ActOnStartClassImplementation(
|
|||
if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
|
||||
Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
|
||||
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
|
||||
} else if ((ODecl = cast_or_null<ObjCInterfaceDecl>(PrevDecl))) {
|
||||
// If we can't find a definition of the interface, warn.
|
||||
if (!(IDecl = ODecl->getDefinition())) {
|
||||
} else if ((IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl))) {
|
||||
// If this is a forward declaration of an interface, warn.
|
||||
if (IDecl->isForwardDecl()) {
|
||||
Diag(ClassLoc, diag::warn_undef_interface) << ClassName;
|
||||
IDecl = 0;
|
||||
}
|
||||
} else {
|
||||
// We did not find anything with the name ClassName; try to correct for
|
||||
|
@ -597,7 +552,7 @@ Sema::DeclPtrTy Sema::ActOnStartClassImplementation(
|
|||
(IDecl = R.getAsSingle<ObjCInterfaceDecl>())) {
|
||||
// Suggest the (potentially) correct interface name. However, put the
|
||||
// fix-it hint itself in a separate note, since changing the name in
|
||||
// the warning would make the fix-it change semantics. Also, don't
|
||||
// the warning would make the fix-it change semantics.However, don't
|
||||
// provide a code-modification hint or use the typo name for recovery,
|
||||
// because this is just a warning. The program may actually be correct.
|
||||
Diag(ClassLoc, diag::warn_undef_interface_suggest)
|
||||
|
@ -644,11 +599,16 @@ Sema::DeclPtrTy Sema::ActOnStartClassImplementation(
|
|||
// FIXME: Do we support attributes on the @implementation? If so we should
|
||||
// copy them over.
|
||||
IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassImplLoc,
|
||||
ClassName, ClassLoc, ODecl, false, true);
|
||||
ClassName, ClassLoc, false, true);
|
||||
IDecl->setSuperClass(SDecl);
|
||||
IDecl->setLocEnd(ClassLoc);
|
||||
|
||||
PushOnScopeChains(IDecl, TUScope);
|
||||
} else {
|
||||
// Mark the interface as being completed, even if it was just as
|
||||
// @class ....;
|
||||
// declaration; the user cannot reopen it.
|
||||
IDecl->setForwardDecl(false);
|
||||
}
|
||||
|
||||
ObjCImplementationDecl* IMPDecl =
|
||||
|
@ -659,15 +619,15 @@ Sema::DeclPtrTy Sema::ActOnStartClassImplementation(
|
|||
return DeclPtrTy::make(IMPDecl);
|
||||
|
||||
// Check that there is no duplicate implementation of this class.
|
||||
if (IDecl && IDecl->getImplementation()) {
|
||||
if (IDecl->getImplementation()) {
|
||||
// FIXME: Don't leak everything!
|
||||
Diag(ClassLoc, diag::err_dup_implementation_class) << ClassName;
|
||||
Diag(IDecl->getImplementation()->getLocation(),
|
||||
diag::note_previous_definition);
|
||||
} else {
|
||||
} else { // add it to the list.
|
||||
IDecl->setImplementation(IMPDecl);
|
||||
PushOnScopeChains(IMPDecl, TUScope);
|
||||
}
|
||||
|
||||
return DeclPtrTy::make(IMPDecl);
|
||||
}
|
||||
|
||||
|
@ -1069,18 +1029,19 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
|
|||
PrevDecl = OI->getInterface();
|
||||
}
|
||||
}
|
||||
ObjCInterfaceDecl *ODecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
|
||||
ObjCInterfaceDecl *IDecl =
|
||||
ObjCInterfaceDecl::Create(Context, CurContext, AtClassLoc,
|
||||
IdentList[i], IdentLocs[i], ODecl, true);
|
||||
|
||||
// Push the ObjCInterfaceDecl on the scope chain but do *not* add it to
|
||||
// the current DeclContext. This prevents clients that walk DeclContext
|
||||
// from seeing the imaginary ObjCInterfaceDecl until it is actually
|
||||
// declared later (if at all). We also take care to explicitly make
|
||||
// sure this declaration is visible for name lookup.
|
||||
PushOnScopeChains(IDecl, TUScope, false);
|
||||
CurContext->makeDeclVisibleInContext(IDecl, true);
|
||||
ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
|
||||
if (!IDecl) { // Not already seen? Make a forward decl.
|
||||
IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassLoc,
|
||||
IdentList[i], IdentLocs[i], true);
|
||||
|
||||
// Push the ObjCInterfaceDecl on the scope chain but do *not* add it to
|
||||
// the current DeclContext. This prevents clients that walk DeclContext
|
||||
// from seeing the imaginary ObjCInterfaceDecl until it is actually
|
||||
// declared later (if at all). We also take care to explicitly make
|
||||
// sure this declaration is visible for name lookup.
|
||||
PushOnScopeChains(IDecl, TUScope, false);
|
||||
CurContext->makeDeclVisibleInContext(IDecl, true);
|
||||
}
|
||||
|
||||
Interfaces.push_back(IDecl);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ void function(Foo * arg)
|
|||
|
||||
// CHECK-scan: [1:1 - 8:1] Invalid Cursor => NoDeclFound
|
||||
// CHECK-scan: [8:1 - 8:8] UnexposedDecl=:8:1
|
||||
// CHECK-scan: [8:8 - 8:11] ObjCClassRef=Foo:8:8
|
||||
// CHECK-scan: [8:8 - 8:11] ObjCClassRef=Foo:10:12
|
||||
// CHECK-scan: [8:11 - 10:1] Invalid Cursor => NoDeclFound
|
||||
// CHECK-scan: [10:1 - 11:5] ObjCInterfaceDecl=Foo:10:12
|
||||
// CHECK-scan: [11:5 - 13:6] Invalid Cursor => NoDeclFound
|
||||
|
|
Загрузка…
Ссылка в новой задаче