aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-12-15 05:27:12 +0000
committerDouglas Gregor <dgregor@apple.com>2011-12-15 05:27:12 +0000
commit2e5c15be82f362611c5928ce853d0685ff98c766 (patch)
tree8b23e367ea5a70ddf92adc54293271df5f5c1d08 /lib/Sema
parentfa39f5b76bafdf536c5e305f821eb1b7f11079bd (diff)
Move the definition-specific data of ObjCInterfaceDecl into a
separately-allocated DefinitionData structure, which we manage the same way as CXXRecordDecl::DefinitionData. This prepares the way for making ObjCInterfaceDecls redeclarable, to more accurately model forward declarations of Objective-C classes and eliminate the mutation of ObjCInterfaceDecl that causes us serious trouble in the AST reader. Note that ObjCInterfaceDecl's accessors are fairly robust against being applied to forward declarations, because Clang (and Sema in particular) doesn't perform RequireCompleteType/hasDefinition() checks everywhere it has to. Each of these overly-robust cases is marked with a FIXME, which we can tackle over time. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146644 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/SemaCodeComplete.cpp5
-rw-r--r--lib/Sema/SemaDeclObjC.cpp18
-rw-r--r--lib/Sema/SemaExprObjC.cpp11
3 files changed, 21 insertions, 13 deletions
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 3d2d0930d8..7e7e87a065 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -4558,7 +4558,7 @@ static void AddObjCMethods(ObjCContainerDecl *Container,
}
ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
- if (!IFace)
+ if (!IFace || !IFace->hasDefinition())
return;
// Add methods in protocols.
@@ -5783,6 +5783,9 @@ static void FindImplementableMethods(ASTContext &Context,
bool InOriginalClass = true) {
if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
// Recurse into protocols.
+ if (!IFace->hasDefinition())
+ return;
+
const ObjCList<ObjCProtocolDecl> &Protocols
= IFace->getReferencedProtocols();
for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index b70c982955..6947d7e211 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -368,10 +368,10 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
ObjCInterfaceDecl* IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
if (IDecl) {
// Class already seen. Is it a forward declaration?
- if (!IDecl->isForwardDecl()) {
+ if (ObjCInterfaceDecl *Def = IDecl->getDefinition()) {
IDecl->setInvalidDecl();
Diag(AtInterfaceLoc, diag::err_duplicate_class_def)<<IDecl->getDeclName();
- Diag(IDecl->getLocation(), diag::note_previous_definition);
+ Diag(Def->getLocation(), diag::note_previous_definition);
// Create a new one; the other may be in a different DeclContex, (e.g.
// this one may be in a LinkageSpecDecl while the other is not) which
@@ -392,8 +392,6 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
IDecl->setLexicalDeclContext(CurContext);
CurContext->addDecl(IDecl);
- IDecl->completedForwardDecl();
-
if (AttrList)
ProcessDeclAttributeList(TUScope, IDecl, AttrList);
}
@@ -406,6 +404,9 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
PushOnScopeChains(IDecl, TUScope);
}
+ if (!IDecl->hasDefinition())
+ IDecl->startDefinition();
+
if (SuperName) {
// Check if a different kind of symbol declared in this scope.
PrevDecl = LookupSingleName(TUScope, SuperName, SuperLoc,
@@ -942,6 +943,7 @@ Decl *Sema::ActOnStartClassImplementation(
// copy them over.
IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassImplLoc,
ClassName, ClassLoc, false, true);
+ IDecl->startDefinition();
IDecl->setSuperClass(SDecl);
IDecl->setLocEnd(ClassLoc);
@@ -950,8 +952,8 @@ Decl *Sema::ActOnStartClassImplementation(
// Mark the interface as being completed, even if it was just as
// @class ....;
// declaration; the user cannot reopen it.
- if (IDecl->isForwardDecl())
- IDecl->completedForwardDecl();
+ if (!IDecl->hasDefinition())
+ IDecl->startDefinition();
}
ObjCImplementationDecl* IMPDecl =
@@ -2540,7 +2542,9 @@ private:
void searchFrom(ObjCInterfaceDecl *iface) {
// A method in a class declaration overrides declarations from
-
+ if (!iface->hasDefinition())
+ return;
+
// - categories,
for (ObjCCategoryDecl *category = iface->getCategoryList();
category; category = category->getNextClassCategory())
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index fbae96071e..20c3b75431 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -512,6 +512,9 @@ ObjCMethodDecl *Sema::LookupPrivateClassMethod(Selector Sel,
ObjCMethodDecl *Sema::LookupPrivateInstanceMethod(Selector Sel,
ObjCInterfaceDecl *ClassDecl) {
+ if (!ClassDecl->hasDefinition())
+ return 0;
+
ObjCMethodDecl *Method = 0;
while (ClassDecl && !Method) {
// If we have implementations in scope, check "private" methods.
@@ -1339,12 +1342,10 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver,
return ExprError();
forwardClass = OCIType->getInterfaceDecl();
+ Method = 0;
+ } else {
+ Method = ClassDecl->lookupInstanceMethod(Sel);
}
-
- // FIXME: consider using LookupInstanceMethodInGlobalPool, since it will be
- // faster than the following method (which can do *many* linear searches).
- // The idea is to add class info to MethodPool.
- Method = ClassDecl->lookupInstanceMethod(Sel);
if (!Method)
// Search protocol qualifiers.