[cfe-commits] r41752 - in /cfe/trunk: AST/ASTContext.cpp AST/Decl.cpp AST/Type.cpp Parse/MinimalAction.cpp Parse/ParseObjc.cpp Parse/Parser.cpp Sema/Sema.h Sema/SemaDecl.cpp Sema/SemaType.cpp include/clang/AST/ASTContext.h include/clang/AST/Decl.h include/clang/AST/Type.h include/clang/Parse/Action.h include/clang/Parse/Parser.h test/Sema/cocoa.m
Steve Naroff
snaroff at apple.com
Thu Sep 6 14:24:24 PDT 2007
Author: snaroff
Date: Thu Sep 6 16:24:23 2007
New Revision: 41752
URL: http://llvm.org/viewvc/llvm-project?rev=41752&view=rev
Log:
The goal of this commit is to get just enough Sema support to recognize Objective-C classes
as types. That said, the AST nodes ObjcInterfaceDecl, ObjcInterfaceType, and ObjcClassDecl are *very*
preliminary.
The good news is we no longer need -parse-noop (aka MinimalActions) to parse cocoa.m.
Modified:
cfe/trunk/AST/ASTContext.cpp
cfe/trunk/AST/Decl.cpp
cfe/trunk/AST/Type.cpp
cfe/trunk/Parse/MinimalAction.cpp
cfe/trunk/Parse/ParseObjc.cpp
cfe/trunk/Parse/Parser.cpp
cfe/trunk/Sema/Sema.h
cfe/trunk/Sema/SemaDecl.cpp
cfe/trunk/Sema/SemaType.cpp
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/test/Sema/cocoa.m
Modified: cfe/trunk/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/ASTContext.cpp?rev=41752&r1=41751&r2=41752&view=diff
==============================================================================
--- cfe/trunk/AST/ASTContext.cpp (original)
+++ cfe/trunk/AST/ASTContext.cpp Thu Sep 6 16:24:23 2007
@@ -596,6 +596,16 @@
return QualType(Decl->TypeForDecl, 0);
}
+/// getObjcInterfaceType - Return the unique reference to the type for the
+/// specified ObjC interface decl.
+QualType ASTContext::getObjcInterfaceType(ObjcInterfaceDecl *Decl) {
+ if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
+
+ Decl->TypeForDecl = new ObjcInterfaceType(Decl);
+ Types.push_back(Decl->TypeForDecl);
+ return QualType(Decl->TypeForDecl, 0);
+}
+
/// getTypeOfExpr - Unlike many "get<Type>" functions, we can't unique
/// TypeOfExpr AST's (since expression's are never shared). For example,
/// multiple declarations that refer to "typeof(x)" all contain different
Modified: cfe/trunk/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Decl.cpp?rev=41752&r1=41751&r2=41752&view=diff
==============================================================================
--- cfe/trunk/AST/Decl.cpp (original)
+++ cfe/trunk/AST/Decl.cpp Thu Sep 6 16:24:23 2007
@@ -25,6 +25,7 @@
static unsigned nEnumDecls = 0;
static unsigned nTypedef = 0;
static unsigned nFieldDecls = 0;
+static unsigned nInterfaceDecls = 0;
static bool StatSwitch = false;
bool Decl::CollectingStats(bool enable) {
@@ -101,6 +102,9 @@
case Enum:
nEnumDecls++;
break;
+ case ObjcInterface:
+ nInterfaceDecls++;
+ break;
}
}
Modified: cfe/trunk/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Type.cpp?rev=41752&r1=41751&r2=41752&view=diff
==============================================================================
--- cfe/trunk/AST/Type.cpp (original)
+++ cfe/trunk/AST/Type.cpp Thu Sep 6 16:24:23 2007
@@ -836,6 +836,12 @@
InnerString = getDecl()->getIdentifier()->getName() + InnerString;
}
+void ObjcInterfaceType::getAsStringInternal(std::string &InnerString) const {
+ if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
+ InnerString = ' ' + InnerString;
+ InnerString = getDecl()->getIdentifier()->getName() + InnerString;
+}
+
void TagType::getAsStringInternal(std::string &InnerString) const {
if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
InnerString = ' ' + InnerString;
Modified: cfe/trunk/Parse/MinimalAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/MinimalAction.cpp?rev=41752&r1=41751&r2=41752&view=diff
==============================================================================
--- cfe/trunk/Parse/MinimalAction.cpp (original)
+++ cfe/trunk/Parse/MinimalAction.cpp Thu Sep 6 16:24:23 2007
@@ -68,12 +68,24 @@
return 0;
}
-/// ParsedObjcClassDeclaration -
+Action::DeclTy *
+MinimalAction::ObjcStartClassInterface(SourceLocation AtInterafceLoc,
+ IdentifierInfo *ClassName, SourceLocation ClassLoc,
+ IdentifierInfo *SuperName, SourceLocation SuperLoc,
+ IdentifierInfo **ProtocolNames, unsigned NumProtocols,
+ AttributeList *AttrList) {
+ TypeNameInfo *TI =
+ new TypeNameInfo(1, ClassName->getFETokenInfo<TypeNameInfo>());
+
+ ClassName->setFETokenInfo(TI);
+ return 0;
+}
+
+/// ObjcClassDeclaration -
/// Scope will always be top level file scope.
Action::DeclTy *
-MinimalAction::ParsedObjcClassDeclaration(Scope *S,
- IdentifierInfo **IdentList,
- unsigned NumElts) {
+MinimalAction::ObjcClassDeclaration(Scope *S, SourceLocation AtClassLoc,
+ IdentifierInfo **IdentList, unsigned NumElts) {
for (unsigned i = 0; i != NumElts; ++i) {
TypeNameInfo *TI =
new TypeNameInfo(1, IdentList[i]->getFETokenInfo<TypeNameInfo>());
Modified: cfe/trunk/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseObjc.cpp?rev=41752&r1=41751&r2=41752&view=diff
==============================================================================
--- cfe/trunk/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/Parse/ParseObjc.cpp Thu Sep 6 16:24:23 2007
@@ -37,7 +37,7 @@
case tok::objc_protocol:
return ParseObjCAtProtocolDeclaration(AtLoc);
case tok::objc_implementation:
- return ParseObjCAtImplementationDeclaration(AtLoc);
+ return ObjcImpDecl = ParseObjCAtImplementationDeclaration(AtLoc);
case tok::objc_end:
return ParseObjCAtEndDeclaration(AtLoc);
case tok::objc_compatibility_alias:
@@ -80,8 +80,8 @@
if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@class"))
return 0;
- return Actions.ParsedObjcClassDeclaration(CurScope,
- &ClassNames[0], ClassNames.size());
+ return Actions.ObjcClassDeclaration(CurScope, atLoc,
+ &ClassNames[0], ClassNames.size());
}
///
@@ -154,8 +154,7 @@
if (attrList) // categories don't support attributes.
Diag(Tok, diag::err_objc_no_attributes_on_category);
- llvm::SmallVector<DeclTy*, 64> MethodDecls;
- ParseObjCInterfaceDeclList(0/*FIXME*/, MethodDecls);
+ ParseObjCInterfaceDeclList(0/*FIXME*/);
// The @ sign was already consumed by ParseObjCInterfaceDeclList().
if (Tok.isObjCAtKeyword(tok::objc_end)) {
@@ -169,11 +168,6 @@
IdentifierInfo *superClassId = 0;
SourceLocation superClassLoc;
- // FIXME: temporary hack to grok class names (until we have sema support).
- llvm::SmallVector<IdentifierInfo *, 1> ClassName;
- ClassName.push_back(nameId);
- Actions.ParsedObjcClassDeclaration(CurScope, &ClassName[0], 1);
-
if (Tok.getKind() == tok::colon) { // a super class is specified.
ConsumeToken();
if (Tok.getKind() != tok::identifier) {
@@ -193,12 +187,10 @@
superClassId, superClassLoc, &ProtocolRefs[0],
ProtocolRefs.size(), attrList);
- llvm::SmallVector<DeclTy*, 32> IvarDecls;
if (Tok.getKind() == tok::l_brace)
- ParseObjCClassInstanceVariables(ClsType, IvarDecls);
+ ParseObjCClassInstanceVariables(ClsType);
- llvm::SmallVector<DeclTy*, 64> MethodDecls;
- ParseObjCInterfaceDeclList(ClsType, MethodDecls);
+ ParseObjCInterfaceDeclList(ClsType);
// The @ sign was already consumed by ParseObjCInterfaceDeclList().
if (Tok.isObjCAtKeyword(tok::objc_end)) {
@@ -213,7 +205,7 @@
/// empty
/// objc-interface-decl-list objc-property-decl [OBJC2]
/// objc-interface-decl-list objc-method-requirement [OBJC2]
-/// objc-interface-decl-list objc-method-proto
+/// objc-interface-decl-list objc-method-proto ';'
/// objc-interface-decl-list declaration
/// objc-interface-decl-list ';'
///
@@ -221,9 +213,7 @@
/// @required
/// @optional
///
-void Parser::ParseObjCInterfaceDeclList(
- DeclTy *interfaceDecl, llvm::SmallVectorImpl<DeclTy*> &MethodDecls) {
- DeclTy *IDecl = 0;
+void Parser::ParseObjCInterfaceDeclList(DeclTy *interfaceDecl) {
while (1) {
if (Tok.getKind() == tok::at) {
SourceLocation AtLoc = ConsumeToken(); // the "@"
@@ -246,8 +236,10 @@
}
}
if (Tok.getKind() == tok::minus || Tok.getKind() == tok::plus) {
- IDecl = ParseObjCMethodPrototype(true);
- MethodDecls.push_back(IDecl);
+ ParseObjCMethodPrototype(interfaceDecl);
+ // Consume the ';' here, since ParseObjCMethodPrototype() is re-used for
+ // method definitions.
+ ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "method proto");
continue;
}
if (Tok.getKind() == tok::semi)
@@ -257,8 +249,7 @@
else {
// FIXME: as the name implies, this rule allows function definitions.
// We could pass a flag or check for functions during semantic analysis.
- IDecl = ParseDeclarationOrFunctionDefinition();
- MethodDecls.push_back(IDecl);
+ ParseDeclarationOrFunctionDefinition();
}
}
}
@@ -355,10 +346,9 @@
}
}
-/// objc-methodproto:
+/// objc-method-proto:
/// objc-instance-method objc-method-decl objc-method-attributes[opt]
-/// ';'[opt]
-/// objc-class-method objc-method-decl objc-method-attributes[opt] ';'[opt]
+/// objc-class-method objc-method-decl objc-method-attributes[opt]
///
/// objc-instance-method: '-'
/// objc-class-method: '+'
@@ -366,19 +356,25 @@
/// objc-method-attributes: [OBJC2]
/// __attribute__((deprecated))
///
-Parser::DeclTy *Parser::ParseObjCMethodPrototype(bool decl) {
+Parser::DeclTy *Parser::ParseObjCMethodPrototype(DeclTy *CDecl) {
assert((Tok.getKind() == tok::minus || Tok.getKind() == tok::plus) &&
"expected +/-");
tok::TokenKind methodType = Tok.getKind();
SourceLocation methodLoc = ConsumeToken();
- // FIXME: deal with "context sensitive" protocol qualifiers in prototypes
DeclTy *MDecl = ParseObjCMethodDecl(methodType, methodLoc);
+
+ AttributeList *methodAttrs = 0;
+ // If attributes exist after the method, parse them.
+ if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute)
+ methodAttrs = ParseAttributes();
+
+ if (CDecl)
+ Actions.ObjcAddMethod(CDecl, MDecl, methodAttrs);
- if (decl)
- // Consume the ';'.
- ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "method proto");
+ // Since this rule is used for both method declarations and definitions,
+ // the caller is responsible for consuming the ';'.
return MDecl;
}
@@ -546,24 +542,13 @@
Declarator ParmDecl(DS, Declarator::PrototypeContext);
ParseDeclarator(ParmDecl);
}
- AttributeList *methodAttrs = 0;
- // If attributes exist after the method, parse them.
- if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute)
- methodAttrs = ParseAttributes();
-
// FIXME: Add support for optional parmameter list...
return Actions.ObjcBuildMethodDeclaration(mLoc, mType, ReturnType,
- &KeyInfo[0], KeyInfo.size(),
- methodAttrs);
+ &KeyInfo[0], KeyInfo.size());
} else if (!selIdent) {
Diag(Tok, diag::err_expected_ident); // missing selector name.
}
- AttributeList *methodAttrs = 0;
- // If attributes exist after the method, parse them.
- if (getLang().ObjC2 && Tok.getKind() == tok::kw___attribute)
- methodAttrs = ParseAttributes();
- return Actions.ObjcBuildMethodDeclaration(mLoc, mType, ReturnType, selIdent,
- methodAttrs);
+ return Actions.ObjcBuildMethodDeclaration(mLoc, mType, ReturnType, selIdent);
}
/// objc-protocol-refs:
@@ -612,9 +597,9 @@
/// objc-instance-variable-decl:
/// struct-declaration
///
-void Parser::ParseObjCClassInstanceVariables(DeclTy *interfaceDecl,
- llvm::SmallVectorImpl<DeclTy*> &IvarDecls) {
+void Parser::ParseObjCClassInstanceVariables(DeclTy *interfaceDecl) {
assert(Tok.getKind() == tok::l_brace && "expected {");
+ llvm::SmallVector<DeclTy*, 16> IvarDecls;
SourceLocation LBraceLoc = ConsumeBrace(); // the "{"
@@ -648,7 +633,10 @@
}
}
ParseStructDeclaration(interfaceDecl, IvarDecls);
-
+ for (unsigned i = 0; i < IvarDecls.size(); i++)
+ Actions.ObjcAddInstanceVariable(interfaceDecl, IvarDecls[i], visibility);
+ IvarDecls.clear();
+
if (Tok.getKind() == tok::semi) {
ConsumeToken();
} else if (Tok.getKind() == tok::r_brace) {
@@ -671,14 +659,14 @@
/// objc-protocol-definition:
/// @protocol identifier
/// objc-protocol-refs[opt]
-/// objc-methodprotolist
+/// objc-interface-decl-list
/// @end
///
/// objc-protocol-forward-reference:
/// @protocol identifier-list ';'
///
/// "@protocol identifier ;" should be resolved as "@protocol
-/// identifier-list ;": objc-methodprotolist may not start with a
+/// identifier-list ;": objc-interface-decl-list may not start with a
/// semicolon in the first alternative if objc-protocol-refs are omitted.
Parser::DeclTy *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc) {
@@ -727,8 +715,7 @@
if (ParseObjCProtocolReferences(ProtocolRefs))
return 0;
}
- llvm::SmallVector<DeclTy*, 64> MethodDecls;
- ParseObjCInterfaceDeclList(0/*FIXME*/, MethodDecls);
+ ParseObjCInterfaceDeclList(0/*FIXME*/);
// The @ sign was already consumed by ParseObjCInterfaceDeclList().
if (Tok.isObjCAtKeyword(tok::objc_end)) {
@@ -794,9 +781,8 @@
}
ConsumeToken(); // Consume super class name
}
- llvm::SmallVector<DeclTy*, 32> IvarDecls;
if (Tok.getKind() == tok::l_brace)
- ParseObjCClassInstanceVariables(0/*FIXME*/, IvarDecls); // we have ivars
+ ParseObjCClassInstanceVariables(0/*FIXME*/); // we have ivars
return 0;
}
@@ -895,12 +881,12 @@
return 0;
}
-/// objc-method-def: objc-methodproto ';'[opt] '{' body '}'
+/// objc-method-def: objc-method-proto ';'[opt] '{' body '}'
///
void Parser::ParseObjCInstanceMethodDefinition() {
assert(Tok.getKind() == tok::minus &&
"ParseObjCInstanceMethodDefinition(): Expected '-'");
- ParseObjCMethodPrototype(false);
+ ParseObjCMethodPrototype(ObjcImpDecl);
// parse optional ';'
if (Tok.getKind() == tok::semi)
ConsumeToken();
@@ -913,12 +899,12 @@
StmtResult FnBody = ParseCompoundStatementBody();
}
-/// objc-method-def: objc-methodproto ';'[opt] '{' body '}'
+/// objc-method-def: objc-method-proto ';'[opt] '{' body '}'
///
void Parser::ParseObjCClassMethodDefinition() {
assert(Tok.getKind() == tok::plus &&
"ParseObjCClassMethodDefinition(): Expected '+'");
- ParseObjCMethodPrototype(false);
+ ParseObjCMethodPrototype(ObjcImpDecl);
// parse optional ';'
if (Tok.getKind() == tok::semi)
ConsumeToken();
Modified: cfe/trunk/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/Parser.cpp?rev=41752&r1=41751&r2=41752&view=diff
==============================================================================
--- cfe/trunk/Parse/Parser.cpp (original)
+++ cfe/trunk/Parse/Parser.cpp Thu Sep 6 16:24:23 2007
@@ -22,6 +22,7 @@
CurScope = 0;
NumCachedScopes = 0;
ParenCount = BracketCount = BraceCount = 0;
+ ObjcImpDecl = 0;
}
/// Out-of-line virtual destructor to provide home for Action class.
Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=41752&r1=41751&r2=41752&view=diff
==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Thu Sep 6 16:24:23 2007
@@ -347,6 +347,17 @@
TypeTy *Ty,
SourceLocation RParenLoc);
+ // Objective-C declarations.
+ virtual DeclTy *ObjcStartClassInterface(SourceLocation AtInterafceLoc,
+ IdentifierInfo *ClassName, SourceLocation ClassLoc,
+ IdentifierInfo *SuperName, SourceLocation SuperLoc,
+ IdentifierInfo **ProtocolNames, unsigned NumProtocols,
+ AttributeList *AttrList);
+
+ virtual DeclTy *ObjcClassDeclaration(Scope *S, SourceLocation AtClassLoc,
+ IdentifierInfo **IdentList,
+ unsigned NumElts);
+
private:
// UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
// functions and arrays to their respective pointers (C99 6.3.2.1).
Modified: cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=41752&r1=41751&r2=41752&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Thu Sep 6 16:24:23 2007
@@ -26,7 +26,11 @@
using namespace clang;
Sema::DeclTy *Sema::isTypeName(const IdentifierInfo &II, Scope *S) const {
- return dyn_cast_or_null<TypedefDecl>(II.getFETokenInfo<Decl>());
+ Decl *IIDecl = II.getFETokenInfo<Decl>();
+ if (dyn_cast_or_null<TypedefDecl>(IIDecl) ||
+ dyn_cast_or_null<ObjcInterfaceDecl>(IIDecl))
+ return IIDecl;
+ return 0;
}
void Sema::PopScope(SourceLocation Loc, Scope *S) {
@@ -835,6 +839,45 @@
return NewTD;
}
+Sema::DeclTy *Sema::ObjcStartClassInterface(SourceLocation AtInterfaceLoc,
+ IdentifierInfo *ClassName, SourceLocation ClassLoc,
+ IdentifierInfo *SuperName, SourceLocation SuperLoc,
+ IdentifierInfo **ProtocolNames, unsigned NumProtocols,
+ AttributeList *AttrList) {
+ assert(ClassName && "Missing class identifier");
+ ObjcInterfaceDecl *IDecl;
+
+ IDecl = new ObjcInterfaceDecl(AtInterfaceLoc, ClassName);
+
+ // Chain & install the interface decl into the identifier.
+ IDecl->setNext(ClassName->getFETokenInfo<Decl>());
+ ClassName->setFETokenInfo(IDecl);
+ return IDecl;
+}
+
+/// ObjcClassDeclaration -
+/// Scope will always be top level file scope.
+Action::DeclTy *
+Sema::ObjcClassDeclaration(Scope *S, SourceLocation AtClassLoc,
+ IdentifierInfo **IdentList, unsigned NumElts) {
+ ObjcClassDecl *CDecl = new ObjcClassDecl(AtClassLoc, NumElts);
+
+ for (unsigned i = 0; i != NumElts; ++i) {
+ ObjcInterfaceDecl *IDecl;
+
+ IDecl = new ObjcInterfaceDecl(SourceLocation(), IdentList[i], true);
+ // Chain & install the interface decl into the identifier.
+ IDecl->setNext(IdentList[i]->getFETokenInfo<Decl>());
+ IdentList[i]->setFETokenInfo(IDecl);
+
+ // Remember that this needs to be removed when the scope is popped.
+ S->AddDecl(IdentList[i]);
+
+ CDecl->setInterfaceDecl((int)i, IDecl);
+ }
+ return CDecl;
+}
+
/// ParseTag - This is invoked when we see 'struct foo' or 'struct {'. In the
/// former case, Name will be non-null. In the later case, Name will be null.
Modified: cfe/trunk/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaType.cpp?rev=41752&r1=41751&r2=41752&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaType.cpp (original)
+++ cfe/trunk/Sema/SemaType.cpp Thu Sep 6 16:24:23 2007
@@ -102,6 +102,10 @@
assert(DS.getTypeSpecWidth() == 0 && DS.getTypeSpecComplex() == 0 &&
DS.getTypeSpecSign() == 0 &&
"Can't handle qualifiers on typedef names yet!");
+ // FIXME: Adding a TST_objcInterface clause doesn't seem ideal, so
+ // we have this "hack" for now...
+ if (isa<ObjcInterfaceDecl>(D))
+ return Ctx.getObjcInterfaceType(cast<ObjcInterfaceDecl>(D));
// TypeQuals handled by caller.
return Ctx.getTypedefType(cast<TypedefDecl>(D));
}
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=41752&r1=41751&r2=41752&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Thu Sep 6 16:24:23 2007
@@ -109,6 +109,7 @@
/// getTypedefType - Return the unique reference to the type for the
/// specified typename decl.
QualType getTypedefType(TypedefDecl *Decl);
+ QualType getObjcInterfaceType(ObjcInterfaceDecl *Decl);
/// getTypeOfType - GCC extension.
QualType getTypeOfExpr(Expr *e);
Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=41752&r1=41751&r2=41752&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Thu Sep 6 16:24:23 2007
@@ -34,7 +34,7 @@
// Concrete sub-classes of ValueDecl
Function, BlockVariable, FileVariable, ParmVariable, EnumConstant,
// Concrete sub-classes of TypeDecl
- Typedef, Struct, Union, Class, Enum,
+ Typedef, Struct, Union, Class, Enum, ObjcInterface, ObjcClass,
// Concrete sub-class of Decl
Field
};
@@ -503,6 +503,47 @@
static bool classof(const RecordDecl *D) { return true; }
};
+class ObjcInterfaceDecl : public TypeDecl {
+ /// Ivars/NumIvars - This is a new[]'d array of pointers to Decls.
+ FieldDecl **Ivars; // Null if not defined.
+ int NumIvars; // -1 if not defined.
+
+ bool isForwardDecl; // declared with @class.
+public:
+ ObjcInterfaceDecl(SourceLocation L, IdentifierInfo *Id, bool FD = false)
+ : TypeDecl(ObjcInterface, L, Id, 0), Ivars(0), NumIvars(-1),
+ isForwardDecl(FD) { }
+
+ void addInstanceVariable(FieldDecl ivar);
+
+ static bool classof(const Decl *D) {
+ return D->getKind() == ObjcInterface;
+ }
+ static bool classof(const ObjcInterfaceDecl *D) { return true; }
+};
+
+class ObjcClassDecl : public TypeDecl {
+ ObjcInterfaceDecl **ForwardDecls; // Null if not defined.
+ int NumForwardDecls; // -1 if not defined.
+public:
+ ObjcClassDecl(SourceLocation L, unsigned nElts)
+ : TypeDecl(ObjcClass, L, 0, 0) {
+ if (nElts) {
+ ForwardDecls = new ObjcInterfaceDecl*[nElts];
+ bzero(ForwardDecls, nElts*sizeof(ObjcInterfaceDecl*));
+ }
+ NumForwardDecls = nElts;
+ }
+ void setInterfaceDecl(int idx, ObjcInterfaceDecl *OID) {
+ assert((idx < NumForwardDecls) && "index out of range");
+ ForwardDecls[idx] = OID;
+ }
+ static bool classof(const Decl *D) {
+ return D->getKind() == ObjcClass;
+ }
+ static bool classof(const ObjcClassDecl *D) { return true; }
+};
+
} // end namespace clang
#endif
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=41752&r1=41751&r2=41752&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Thu Sep 6 16:24:23 2007
@@ -31,6 +31,7 @@
class TagDecl;
class RecordDecl;
class EnumDecl;
+ class ObjcInterfaceDecl;
class Expr;
class SourceLocation;
class PointerType;
@@ -203,6 +204,7 @@
Vector, OCUVector,
FunctionNoProto, FunctionProto,
TypeName, Tagged,
+ ObjcInterface,
TypeOfExp, TypeOfTyp // GNU typeof extension.
};
private:
@@ -810,6 +812,23 @@
static bool classof(const TagType *) { return true; }
};
+class ObjcInterfaceType : public Type {
+ ObjcInterfaceDecl *Decl;
+ ObjcInterfaceType(ObjcInterfaceDecl *D) :
+ Type(ObjcInterface, QualType()), Decl(D) { }
+ friend class ASTContext; // ASTContext creates these.
+public:
+
+ ObjcInterfaceDecl *getDecl() const { return Decl; }
+
+ virtual void getAsStringInternal(std::string &InnerString) const;
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == ObjcInterface;
+ }
+ static bool classof(const ObjcInterfaceType *) { return true; }
+};
+
/// RecordType - This is a helper class that allows the use of isa/cast/dyncast
/// to detect TagType objects of structs/unions/classes.
class RecordType : public TagType {
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=41752&r1=41751&r2=41752&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Thu Sep 6 16:24:23 2007
@@ -136,9 +136,9 @@
return 0;
}
- virtual DeclTy *ParsedObjcClassDeclaration(Scope *S,
- IdentifierInfo **IdentList,
- unsigned NumElts) {
+ virtual DeclTy *ObjcClassDeclaration(Scope *S, SourceLocation AtClassLoc,
+ IdentifierInfo **IdentList,
+ unsigned NumElts) {
return 0;
}
@@ -440,25 +440,30 @@
AttributeList *AttrList) {
return 0;
}
- virtual void ObjCContinueClassInterface(SourceLocation InterfaceLoc) {
+ virtual void ObjcAddInstanceVariable(DeclTy *ClassDec, DeclTy *Ivars,
+ tok::ObjCKeywordKind visibility) {
return;
}
- virtual void ObjCStartCategoryInterface() {
- return;
- }
- virtual void ObjCFinishInterface() {
+ virtual void ObjcAddMethod(DeclTy *ClassDec, DeclTy *Meth,
+ AttributeList *AttrList) {
return;
}
virtual DeclTy *ObjcBuildMethodDeclaration(
SourceLocation MethodLoc, tok::TokenKind MethodType, TypeTy *ReturnType,
- ObjcKeywordInfo *Keywords, unsigned NumKeywords, AttributeList *attrs) {
+ ObjcKeywordInfo *Keywords, unsigned NumKeywords) {
return 0;
}
virtual DeclTy *ObjcBuildMethodDeclaration(
SourceLocation MethodLoc, tok::TokenKind MethodType, TypeTy *ReturnType,
- IdentifierInfo *SelectorName, AttributeList *attrs) {
+ IdentifierInfo *SelectorName) {
return 0;
}
+ virtual void ObjCStartCategoryInterface() { // FIXME
+ return;
+ }
+ virtual void ObjCFinishInterface() {
+ return;
+ }
//===----------------------- Obj-C Expressions --------------------------===//
virtual ExprResult ParseObjCStringLiteral(ExprTy *string) {
@@ -496,10 +501,15 @@
/// they are removed from the IdentifierInfo::FETokenInfo field.
virtual void PopScope(SourceLocation Loc, Scope *S);
- virtual DeclTy *ParsedObjcClassDeclaration(Scope *S,
- IdentifierInfo **IdentList,
- unsigned NumElts);
+ virtual DeclTy *ObjcClassDeclaration(Scope *S, SourceLocation AtClassLoc,
+ IdentifierInfo **IdentList,
+ unsigned NumElts);
+ virtual DeclTy *ObjcStartClassInterface(SourceLocation AtInterafceLoc,
+ IdentifierInfo *ClassName, SourceLocation ClassLoc,
+ IdentifierInfo *SuperName, SourceLocation SuperLoc,
+ IdentifierInfo **ProtocolNames, unsigned NumProtocols,
+ AttributeList *AttrList);
};
} // end namespace clang
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=41752&r1=41751&r2=41752&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Thu Sep 6 16:24:23 2007
@@ -253,17 +253,17 @@
void ParseSimpleAsm();
void ParseAsmStringLiteral();
- // Objective-C External Declarations
+ // Objective-C External Declarations
DeclTy *ParseObjCAtDirectives();
DeclTy *ParseObjCAtClassDeclaration(SourceLocation atLoc);
DeclTy *ParseObjCAtInterfaceDeclaration(SourceLocation atLoc,
AttributeList *prefixAttrs = 0);
- void ParseObjCClassInstanceVariables(DeclTy *interfaceDecl,
- llvm::SmallVectorImpl<DeclTy*> &IvarDecls);
+ void ParseObjCClassInstanceVariables(DeclTy *interfaceDecl);
bool ParseObjCProtocolReferences(llvm::SmallVectorImpl<IdentifierInfo*> &);
- void ParseObjCInterfaceDeclList(DeclTy *interfaceDecl,
- llvm::SmallVectorImpl<DeclTy*> &MethodDecls);
+ void ParseObjCInterfaceDeclList(DeclTy *interfaceDecl);
DeclTy *ParseObjCAtProtocolDeclaration(SourceLocation atLoc);
+
+ DeclTy *ObjcImpDecl;
DeclTy *ParseObjCAtImplementationDeclaration(SourceLocation atLoc);
DeclTy *ParseObjCAtEndDeclaration(SourceLocation atLoc);
DeclTy *ParseObjCAtAliasDeclaration(SourceLocation atLoc);
@@ -288,7 +288,7 @@
TypeTy *ParseObjCTypeName();
void ParseObjCMethodRequirement();
- DeclTy *ParseObjCMethodPrototype(bool decl);
+ DeclTy *ParseObjCMethodPrototype(DeclTy *classOrCat);
DeclTy *ParseObjCMethodDecl(tok::TokenKind mType, SourceLocation mLoc);
void ParseObjCPropertyAttribute(DeclTy *interfaceDecl);
void ParseObjCPropertyDecl(DeclTy *interfaceDecl);
Modified: cfe/trunk/test/Sema/cocoa.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/cocoa.m?rev=41752&r1=41751&r2=41752&view=diff
==============================================================================
--- cfe/trunk/test/Sema/cocoa.m (original)
+++ cfe/trunk/test/Sema/cocoa.m Thu Sep 6 16:24:23 2007
@@ -1,4 +1,4 @@
-// RUN: clang %s -parse-noop -arch ppc
+// RUN: clang %s -arch ppc
#ifdef __APPLE__
#include <Cocoa/Cocoa.h>
#endif
More information about the cfe-commits
mailing list