//===--- SemaDeclObjC.cpp - Semantic Analysis for ObjC Declarations -------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements semantic analysis for Objective C declarations.
//
//===----------------------------------------------------------------------===//
#include "Sema.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Parse/DeclSpec.h"
using namespace clang;
/// ObjCActOnStartOfMethodDef - This routine sets up parameters; invisible
/// and user declared, in the method definition's AST.
void Sema::ObjCActOnStartOfMethodDef(Scope *FnBodyScope, DeclTy *D) {
assert(getCurMethodDecl() == 0 && "Method parsing confused");
ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>((Decl *)D);
// If we don't have a valid method decl, simply return.
if (!MDecl)
return;
// Allow the rest of sema to find private method decl implementations.
if (MDecl->isInstance())
AddInstanceMethodToGlobalPool(MDecl);
else
AddFactoryMethodToGlobalPool(MDecl);
// Allow all of Sema to see that we are entering a method definition.
PushDeclContext(MDecl);
// Create Decl objects for each parameter, entrring them in the scope for
// binding to their use.
// Insert the invisible arguments, self and _cmd!
MDecl->createImplicitParams(Context);
PushOnScopeChains(MDecl->getSelfDecl(), FnBodyScope);
PushOnScopeChains(MDecl->getCmdDecl(), FnBodyScope);
// Introduce all of the other parameters into this scope.
for (unsigned i = 0, e = MDecl->getNumParams(); i != e; ++i) {
ParmVarDecl *PDecl = MDecl->getParamDecl(i);
IdentifierInfo *II = PDecl->getIdentifier();
if (II)
PushOnScopeChains(PDecl, FnBodyScope);
}
}
Sema::DeclTy *Sema::
ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
IdentifierInfo *ClassName, SourceLocation ClassLoc,
IdentifierInfo *SuperName, SourceLocation SuperLoc,
DeclTy * const *ProtoRefs, unsigned NumProtoRefs,
SourceLocation EndProtoLoc, AttributeList *AttrList) {
assert(ClassName && "Missing class identifier");
// Check for another declaration kind with the same name.
Decl *PrevDecl = LookupDecl(ClassName, Decl::IDNS_Ordinary, TUScope);
if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
Diag(ClassLoc, diag::err_redefinition_different_kind,
ClassName->getName());
Diag(PrevDecl->getLocation(), diag::err_previous_definition);
}
ObjCInterfaceDecl* IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
if (IDecl) {
// Class already seen. Is it a forward declaration?
if (!IDecl->isForwardDecl())
Diag(AtInterfaceLoc, diag::err_duplicate_class_def, IDecl->getName());
else {
IDecl->setLocation(AtInterfaceLoc);
IDecl->setForwardDecl(false);
}
} else {
IDecl = ObjCInterfaceDecl::Create(Context, AtInterfaceLoc,
ClassName, ClassLoc);
if (AttrList)
ProcessDeclAttributeList(IDecl, AttrList);
ObjCInterfaceDecls[ClassName] = IDecl;
// Remember that this needs to be removed when the scope is popped.
TUScope->AddDecl(IDecl);
}
if (SuperName) {
ObjCInterfaceDecl* SuperClassEntry = 0;
// C