//===--- 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/Parse/Scope.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(CurFunctionDecl == 0 && "Method parsing confused");
ObjCMethodDecl *MDecl = dyn_cast<ObjCMethodDecl>(static_cast<Decl *>(D));
assert(MDecl != 0 && "Not a method declarator!");
// 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.
CurMethodDecl = MDecl;
PushDeclContext(MDecl);
// Create Decl objects for each parameter, entrring them in the scope for
// binding to their use.
struct DeclaratorChunk::ParamInfo PI;
// Insert the invisible arguments, self and _cmd!
PI.Ident = &Context.Idents.get("self");
PI.IdentLoc = SourceLocation(); // synthesized vars have a null location.
QualType selfTy = Context.getObjCIdType();
if (MDecl->isInstance()) {
if (ObjCInterfaceDecl *OID = MDecl->getClassInterface()) {
// There may be no interface context due to error in declaration of the
// interface (which has been reported). Recover gracefully
selfTy = Context.getObjCInterfaceType(OID);
selfTy = Context.getPointerType(selfTy);
}
}
CurMethodDecl->setSelfDecl(CreateImplicitParameter(FnBodyScope, PI.Ident,
PI.IdentLoc, selfTy));
PI.Ident = &Context.Idents.get("_cmd");
CreateImplicitParameter(FnBodyScope, PI.Ident, PI.IdentLoc,
Context.getObjCSelType());
// 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,
IdentifierInfo **ProtocolNames, unsigned NumProtocols,
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->