[cfe-commits] r42856 - in /cfe/trunk: AST/ASTContext.cpp AST/Type.cpp Parse/ParseDecl.cpp Parse/ParseObjc.cpp Sema/Sema.h Sema/SemaDecl.cpp Sema/SemaType.cpp clang.xcodeproj/project.pbxproj include/clang/AST/ASTContext.h include/clang/AST/Type.h include/clang/Parse/Action.h include/clang/Parse/DeclSpec.h include/clang/Parse/Parser.h test/Sema/class-conforming-protocol-1.m
Fariborz Jahanian
fjahanian at apple.com
Wed Oct 10 17:55:41 PDT 2007
Author: fjahanian
Date: Wed Oct 10 19:55:41 2007
New Revision: 42856
URL: http://llvm.org/viewvc/llvm-project?rev=42856&view=rev
Log:
Patch to create protocol conforming class types.
Added:
cfe/trunk/test/Sema/class-conforming-protocol-1.m
Modified:
cfe/trunk/AST/ASTContext.cpp
cfe/trunk/AST/Type.cpp
cfe/trunk/Parse/ParseDecl.cpp
cfe/trunk/Parse/ParseObjc.cpp
cfe/trunk/Sema/Sema.h
cfe/trunk/Sema/SemaDecl.cpp
cfe/trunk/Sema/SemaType.cpp
cfe/trunk/clang.xcodeproj/project.pbxproj
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/include/clang/Parse/DeclSpec.h
cfe/trunk/include/clang/Parse/Parser.h
Modified: cfe/trunk/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/ASTContext.cpp?rev=42856&r1=42855&r2=42856&view=diff
==============================================================================
--- cfe/trunk/AST/ASTContext.cpp (original)
+++ cfe/trunk/AST/ASTContext.cpp Wed Oct 10 19:55:41 2007
@@ -610,6 +610,31 @@
return QualType(Decl->TypeForDecl, 0);
}
+/// getObjcQualifiedInterfaceType - Return a
+/// ObjcQualifiedInterfaceType type for the given interface decl and
+/// the conforming protocol list.
+QualType ASTContext::getObjcQualifiedInterfaceType(ObjcInterfaceDecl *Decl,
+ ObjcProtocolDecl **Protocols, unsigned NumProtocols) {
+ ObjcInterfaceType *IType =
+ cast<ObjcInterfaceType>(getObjcInterfaceType(Decl));
+
+ llvm::FoldingSetNodeID ID;
+ ObjcQualifiedInterfaceType::Profile(ID, IType, Protocols, NumProtocols);
+
+ void *InsertPos = 0;
+ if (ObjcQualifiedInterfaceType *QT =
+ ObjcQualifiedInterfaceTypes.FindNodeOrInsertPos(ID, InsertPos))
+ return QualType(QT, 0);
+
+ // No Match;
+ ObjcQualifiedInterfaceType *QType = new ObjcQualifiedInterfaceType(IType);
+ for (unsigned i = 0; i != NumProtocols; i++)
+ QType->setProtocols(Protocols[i]);
+ Types.push_back(QType);
+ ObjcQualifiedInterfaceTypes.InsertNode(QType, InsertPos);
+ return QualType(QType, 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/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Type.cpp?rev=42856&r1=42855&r2=42856&view=diff
==============================================================================
--- cfe/trunk/AST/Type.cpp (original)
+++ cfe/trunk/AST/Type.cpp Wed Oct 10 19:55:41 2007
@@ -618,6 +618,19 @@
Profile(ID, getResultType(), arg_type_begin(), NumArgs, isVariadic());
}
+void ObjcQualifiedInterfaceType::Profile(llvm::FoldingSetNodeID &ID,
+ ObjcInterfaceType *interfaceType,
+ ObjcProtocolDecl **protocols,
+ unsigned NumProtocols) {
+ ID.AddPointer(interfaceType);
+ for (unsigned i = 0; i != NumProtocols; i++)
+ ID.AddPointer(protocols[i]);
+}
+
+void ObjcQualifiedInterfaceType::Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, getInterfaceType(), &Protocols[0], getNumProtocols());
+}
+
/// LookThroughTypedefs - Return the ultimate type this typedef corresponds to
/// potentially looking through *all* consequtive typedefs. This returns the
/// sum of the type qualifiers, so if you have:
@@ -843,6 +856,18 @@
InnerString = getDecl()->getIdentifier()->getName() + InnerString;
}
+void ObjcQualifiedInterfaceType::getAsStringInternal(
+ std::string &InnerString) const {
+ InnerString = getInterfaceType()->getDecl()->getName() + '<';
+ int num = getNumProtocols();
+ for (int i = 0; i < num; i++) {
+ InnerString += getProtocols(i)->getName();
+ if (i < num-1)
+ InnerString += ',';
+ }
+ 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/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseDecl.cpp?rev=42856&r1=42855&r2=42856&view=diff
==============================================================================
--- cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/Parse/ParseDecl.cpp Wed Oct 10 19:55:41 2007
@@ -403,18 +403,20 @@
TypeRep);
if (isInvalid)
break;
- else { // FIXME: restrict this to "id" and ObjC classnames.
- DS.Range.setEnd(Tok.getLocation());
- ConsumeToken(); // The identifier
- if (Tok.is(tok::less)) {
- llvm::SmallVector<IdentifierInfo *, 8> ProtocolRefs;
- ParseObjCProtocolReferences(ProtocolRefs);
- Actions.ActOnFindProtocolDeclaration(Loc,
- &ProtocolRefs[0],
- ProtocolRefs.size());
- }
- continue;
+ // FIXME: restrict this to "id" and ObjC classnames.
+ DS.Range.setEnd(Tok.getLocation());
+ ConsumeToken(); // The identifier
+ if (Tok.is(tok::less)) {
+ llvm::SmallVector<IdentifierInfo *, 8> ProtocolRefs;
+ ParseObjCProtocolReferences(ProtocolRefs);
+ llvm::SmallVector<DeclTy *, 8> *ProtocolDecl =
+ new llvm::SmallVector<DeclTy *, 8>;
+ DS.setProtocolQualifiers(ProtocolDecl);
+ Actions.FindProtocolDeclaration(Loc,
+ &ProtocolRefs[0], ProtocolRefs.size(),
+ *ProtocolDecl);
}
+ continue;
}
}
// FALL THROUGH.
Modified: cfe/trunk/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseObjc.cpp?rev=42856&r1=42855&r2=42856&view=diff
==============================================================================
--- cfe/trunk/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/Parse/ParseObjc.cpp Wed Oct 10 19:55:41 2007
@@ -378,9 +378,9 @@
assert((Tok.is(tok::minus) || Tok.is(tok::plus)) && "expected +/-");
tok::TokenKind methodType = Tok.getKind();
- SourceLocation methodLoc = ConsumeToken();
+ ConsumeToken();
- DeclTy *MDecl = ParseObjCMethodDecl(methodType, methodLoc, MethodImplKind);
+ DeclTy *MDecl = ParseObjCMethodDecl(methodType, MethodImplKind);
// Since this rule is used for both method declarations and definitions,
// the caller is (optionally) responsible for consuming the ';'.
return MDecl;
@@ -394,7 +394,7 @@
/// unsigned long const short volatile signed restrict _Complex
/// in out inout bycopy byref oneway int char float double void _Bool
///
-IdentifierInfo *Parser::ParseObjCSelector() {
+IdentifierInfo *Parser::ParseObjCSelector(SourceLocation &SelectorLoc) {
switch (Tok.getKind()) {
default:
return 0;
@@ -438,7 +438,7 @@
case tok::kw__Bool:
case tok::kw__Complex:
IdentifierInfo *II = Tok.getIdentifierInfo();
- ConsumeToken();
+ SelectorLoc = ConsumeToken();
return II;
}
}
@@ -526,15 +526,14 @@
/// __attribute__((unused))
///
Parser::DeclTy *Parser::ParseObjCMethodDecl(tok::TokenKind mType,
- SourceLocation mLoc,
tok::ObjCKeywordKind MethodImplKind)
{
// Parse the return type.
TypeTy *ReturnType = 0;
if (Tok.is(tok::l_paren))
ReturnType = ParseObjCTypeName();
-
- IdentifierInfo *SelIdent = ParseObjCSelector();
+ SourceLocation mLoc;
+ IdentifierInfo *SelIdent = ParseObjCSelector(mLoc);
if (Tok.isNot(tok::colon)) {
if (!SelIdent) {
Diag(Tok, diag::err_expected_ident); // missing selector name.
@@ -584,7 +583,8 @@
ConsumeToken(); // Eat the identifier.
// Check for another keyword selector.
- SelIdent = ParseObjCSelector();
+ SourceLocation Loc;
+ SelIdent = ParseObjCSelector(Loc);
if (!SelIdent && Tok.isNot(tok::colon))
break;
// We have a selector or a colon, continue parsing.
@@ -1175,7 +1175,8 @@
ReceiverExpr = Res.Val;
}
// Parse objc-selector
- IdentifierInfo *selIdent = ParseObjCSelector();
+ SourceLocation Loc;
+ IdentifierInfo *selIdent = ParseObjCSelector(Loc);
llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
llvm::SmallVector<Action::ExprTy *, 12> KeyExprs;
@@ -1201,7 +1202,7 @@
KeyExprs.push_back(Res.Val);
// Check for another keyword selector.
- selIdent = ParseObjCSelector();
+ selIdent = ParseObjCSelector(Loc);
if (!selIdent && Tok.isNot(tok::colon))
break;
// We have a selector or a colon, continue parsing.
Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=42856&r1=42855&r2=42856&view=diff
==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Wed Oct 10 19:55:41 2007
@@ -449,9 +449,11 @@
IdentifierInfo **IdentList,
unsigned NumElts);
- virtual DeclTy **ActOnFindProtocolDeclaration(SourceLocation TypeLoc,
- IdentifierInfo **ProtocolId,
- unsigned NumProtocols);
+ virtual void FindProtocolDeclaration(SourceLocation TypeLoc,
+ IdentifierInfo **ProtocolId,
+ unsigned NumProtocols,
+ llvm::SmallVector<DeclTy *, 8> &
+ Protocols);
virtual void ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *ClassDecl,
DeclTy **allMethods, unsigned allNum);
Modified: cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=42856&r1=42855&r2=42856&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Wed Oct 10 19:55:41 2007
@@ -987,20 +987,22 @@
return PDecl;
}
-/// ActOnFindProtocolDeclaration - This routine looks for a previously
-/// declared protocol and returns it. If not found, issues diagnostic.
-/// Will build a list of previously protocol declarations found in the list.
-Action::DeclTy **
-Sema::ActOnFindProtocolDeclaration(SourceLocation TypeLoc,
- IdentifierInfo **ProtocolId,
- unsigned NumProtocols) {
+/// FindProtocolDeclaration - This routine looks up protocols and
+/// issuer error if they are not declared. It returns list of protocol
+/// declarations in its 'Protocols' argument.
+void
+Sema::FindProtocolDeclaration(SourceLocation TypeLoc,
+ IdentifierInfo **ProtocolId,
+ unsigned NumProtocols,
+ llvm::SmallVector<DeclTy *,8> &Protocols) {
for (unsigned i = 0; i != NumProtocols; ++i) {
ObjcProtocolDecl *PDecl = ObjcProtocols[ProtocolId[i]];
if (!PDecl)
Diag(TypeLoc, diag::err_undeclared_protocol,
ProtocolId[i]->getName());
+ else
+ Protocols.push_back(PDecl);
}
- return 0;
}
/// ActOnForwardProtocolDeclaration -
Modified: cfe/trunk/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaType.cpp?rev=42856&r1=42855&r2=42856&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaType.cpp (original)
+++ cfe/trunk/Sema/SemaType.cpp Wed Oct 10 19:55:41 2007
@@ -104,8 +104,15 @@
"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));
+ if (ObjcInterfaceDecl *ObjcIntDecl = dyn_cast<ObjcInterfaceDecl>(D)) {
+ if (DS.getProtocolQualifiers() == 0)
+ return Ctx.getObjcInterfaceType(ObjcIntDecl);
+
+ Action::DeclTy **PPDecl = &(*DS.getProtocolQualifiers())[0];
+ return Ctx.getObjcQualifiedInterfaceType(ObjcIntDecl,
+ reinterpret_cast<ObjcProtocolDecl**>(PPDecl),
+ DS.NumProtocolQualifiers());
+ }
// TypeQuals handled by caller.
return Ctx.getTypedefType(cast<TypedefDecl>(D));
}
Modified: cfe/trunk/clang.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/clang.xcodeproj/project.pbxproj?rev=42856&r1=42855&r2=42856&view=diff
==============================================================================
--- cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/trunk/clang.xcodeproj/project.pbxproj Wed Oct 10 19:55:41 2007
@@ -739,6 +739,7 @@
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
+ compatibilityVersion = "Xcode 2.4";
hasScannedForEncodings = 1;
mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
projectDirPath = "";
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=42856&r1=42855&r2=42856&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Wed Oct 10 19:55:41 2007
@@ -38,6 +38,7 @@
llvm::FoldingSet<VectorType> VectorTypes;
llvm::FoldingSet<FunctionTypeNoProto> FunctionTypeNoProtos;
llvm::FoldingSet<FunctionTypeProto> FunctionTypeProtos;
+ llvm::FoldingSet<ObjcQualifiedInterfaceType> ObjcQualifiedInterfaceTypes;
llvm::DenseMap<const RecordDecl*, const RecordLayout*> RecordLayoutInfo;
RecordDecl *CFConstantStringTypeDecl;
public:
@@ -118,6 +119,12 @@
/// specified typename decl.
QualType getTypedefType(TypedefDecl *Decl);
QualType getObjcInterfaceType(ObjcInterfaceDecl *Decl);
+
+ /// getObjcQualifiedInterfaceType - Return a
+ /// ObjcQualifiedInterfaceType type for the given interface decl and
+ /// the conforming protocol list.
+ QualType getObjcQualifiedInterfaceType(ObjcInterfaceDecl *Decl,
+ ObjcProtocolDecl **ProtocolList, unsigned NumProtocols);
/// getTypeOfType - GCC extension.
QualType getTypeOfExpr(Expr *e);
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=42856&r1=42855&r2=42856&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Wed Oct 10 19:55:41 2007
@@ -47,6 +47,7 @@
class FunctionType;
class OCUVectorType;
class BuiltinType;
+ class ObjcQualifiedInterfaceType;
/// QualType - For efficiency, we don't store CVR-qualified types as nodes on
/// their own: instead each reference to a type stores the qualifiers. This
@@ -817,6 +818,7 @@
class ObjcInterfaceType : public Type {
ObjcInterfaceDecl *Decl;
+
ObjcInterfaceType(ObjcInterfaceDecl *D) :
Type(ObjcInterface, QualType()), Decl(D) { }
friend class ASTContext; // ASTContext creates these.
@@ -825,7 +827,7 @@
ObjcInterfaceDecl *getDecl() const { return Decl; }
virtual void getAsStringInternal(std::string &InnerString) const;
-
+
static bool classof(const Type *T) {
return T->getTypeClass() == ObjcInterface;
}
@@ -836,7 +838,7 @@
/// conforming to a list of protocols; such as, INTF<Proto1, Proto2, Proto1>.
/// Duplicate protocols are removed and protocol list is canonicalized to be in
/// alphabetical order.
-class ObjcQualifiedInterfaceType : public Type {
+class ObjcQualifiedInterfaceType : public Type, public llvm::FoldingSetNode {
// Interface type for this protocol conforming object type
ObjcInterfaceType *InterfaceType;
@@ -846,10 +848,29 @@
ObjcQualifiedInterfaceType(ObjcInterfaceType *T) :
Type(ObjcQualifiedInterface, QualType()), InterfaceType(T) { }
+
+ void setProtocols(ObjcProtocolDecl *pType) {
+ Protocols.push_back(pType);
+ }
+ friend class ASTContext; // ASTContext creates these.
public:
ObjcInterfaceType *getInterfaceType() const { return InterfaceType; }
-
+
+ ObjcProtocolDecl *getProtocols(unsigned i) const {
+ return Protocols[i];
+ }
+ unsigned getNumProtocols() const {
+ return Protocols.size();
+ }
+
+ virtual void getAsStringInternal(std::string &InnerString) const;
+
+ void Profile(llvm::FoldingSetNodeID &ID);
+ static void Profile(llvm::FoldingSetNodeID &ID,
+ ObjcInterfaceType *interfaceType,
+ ObjcProtocolDecl **protocols, unsigned NumProtocols);
+
static bool classof(const Type *T) {
return T->getTypeClass() == ObjcQualifiedInterface;
}
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=42856&r1=42855&r2=42856&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Wed Oct 10 19:55:41 2007
@@ -552,13 +552,14 @@
return 0;
}
- /// ActOnFindProtocolDeclaration - This routine looks for a previously
- /// declared protocol and returns it. If not found, issues diagnostic.
- /// Will build a list of previously protocol declarations found in the list.
- virtual DeclTy **ActOnFindProtocolDeclaration(SourceLocation TypeLoc,
- IdentifierInfo **ProtocolId,
- unsigned NumProtocols) {
- return 0;
+ /// FindProtocolDeclaration - This routine looks up protocols and
+ /// issues error if they are not declared. It returns list of valid
+ /// protocols found.
+ virtual void FindProtocolDeclaration(SourceLocation TypeLoc,
+ IdentifierInfo **ProtocolId,
+ unsigned NumProtocols,
+ llvm::SmallVector<DeclTy *, 8> &
+ Protocols) {
}
Modified: cfe/trunk/include/clang/Parse/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/DeclSpec.h?rev=42856&r1=42855&r2=42856&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Parse/DeclSpec.h Wed Oct 10 19:55:41 2007
@@ -124,6 +124,9 @@
// attributes.
AttributeList *AttrList;
+ // List of protocol qualifiers for objective-c classes.
+ llvm::SmallVector<Action::DeclTy *, 8> *ProtocolQualifiers;
+
// SourceLocation info. These are null if the item wasn't specified or if
// the setting was synthesized.
SourceLocation StorageClassSpecLoc, SCS_threadLoc;
@@ -142,10 +145,12 @@
TypeQualifiers(TSS_unspecified),
FS_inline_specified(false),
TypeRep(0),
- AttrList(0) {
+ AttrList(0),
+ ProtocolQualifiers(0) {
}
~DeclSpec() {
delete AttrList;
+ delete ProtocolQualifiers;
}
// storage-class-specifier
SCS getStorageClassSpec() const { return StorageClassSpec; }
@@ -248,6 +253,15 @@
}
AttributeList *getAttributes() const { return AttrList; }
+ llvm::SmallVector<Action::DeclTy *, 8> *getProtocolQualifiers() const {
+ return ProtocolQualifiers;
+ }
+ void setProtocolQualifiers(llvm::SmallVector<Action::DeclTy *, 8> *protos) {
+ ProtocolQualifiers = protos;
+ }
+ unsigned NumProtocolQualifiers() const {
+ return ProtocolQualifiers ? ProtocolQualifiers->size() : 0;
+ }
/// Finish - This does final analysis of the declspec, issuing diagnostics for
/// things like "_Imaginary" (lacking an FP type). After calling this method,
/// DeclSpec is guaranteed self-consistent, even if an error occurred.
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=42856&r1=42855&r2=42856&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Wed Oct 10 19:55:41 2007
@@ -275,7 +275,7 @@
DeclTy *ParseObjCTryStmt(SourceLocation atLoc);
DeclTy *ParseObjCThrowStmt(SourceLocation atLoc);
- IdentifierInfo *ParseObjCSelector();
+ IdentifierInfo *ParseObjCSelector(SourceLocation &MethodLocation);
// Definitions for Objective-c context sensitive keywords recognition.
enum ObjCTypeQual {
objc_in=0, objc_out, objc_inout, objc_oneway, objc_bycopy, objc_byref,
@@ -295,7 +295,7 @@
void ParseObjCMethodRequirement();
DeclTy *ParseObjCMethodPrototype(DeclTy *classOrCat,
tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword);
- DeclTy *ParseObjCMethodDecl(tok::TokenKind mType, SourceLocation mLoc,
+ DeclTy *ParseObjCMethodDecl(tok::TokenKind mType,
tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword);
void ParseObjCPropertyAttribute(DeclTy *interfaceDecl);
void ParseObjCPropertyDecl(DeclTy *interfaceDecl);
Added: cfe/trunk/test/Sema/class-conforming-protocol-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/class-conforming-protocol-1.m?rev=42856&view=auto
==============================================================================
--- cfe/trunk/test/Sema/class-conforming-protocol-1.m (added)
+++ cfe/trunk/test/Sema/class-conforming-protocol-1.m Wed Oct 10 19:55:41 2007
@@ -0,0 +1,21 @@
+// RUN: clang -fsyntax-only -verify %s
+
+ at protocol P1 @end
+ at protocol P2 @end
+ at protocol P3 @end
+
+ at interface INTF
+- (INTF*) METH1; // expected-error {{previous declaration is here}}
+- (INTF<P1>*) METH1; // expected-error {{duplicate declaration of method 'METH1'}}
+
+- (INTF<P1,P2>*) METH2;
+- (INTF<P2,P1>*) METH2; // expected-error {{previous declaration is here}}
+- (INTF<P2,P1,P3>*) METH2; // expected-error {{duplicate declaration of method 'METH2'}}
+
+- (INTF<P2,P1,P3>*) METH3;
+- (INTF<P3,P1,P2, P3>*) METH3;
+
+ at end
+
+INTF<P2,P1,P3>* p1;
+
More information about the cfe-commits
mailing list