Introduce a new OpaquePtr<N> struct type, which is a simple POD wrapper for a
pointer. Its purpose in life is to be a glorified void*, but which does not
implicitly convert to void* or other OpaquePtr's with a different UID.
Introduce Action::DeclPtrTy which is a typedef for OpaquePtr<0>. Change the
entire parser/sema interface to use DeclPtrTy instead of DeclTy*. This
makes the C++ compiler enforce that these aren't convertible to other opaque
types.
We should also convert ExprTy, StmtTy, TypeTy, AttrTy, BaseTy, etc,
but I don't plan to do that in the short term.
The one outstanding known problem with this patch is that we lose the
bitmangling optimization where ActionResult<DeclPtrTy> doesn't know how to
bitmangle the success bit into the low bit of DeclPtrTy. I will rectify
this with a subsequent patch.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67952 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index ba35333..8809eb9 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -20,9 +20,9 @@
/// ActOnStartOfObjCMethodDef - This routine sets up parameters; invisible
/// and user declared, in the method definition's AST.
-void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, DeclTy *D) {
+void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, DeclPtrTy D) {
assert(getCurMethodDecl() == 0 && "Method parsing confused");
- ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>((Decl *)D);
+ ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D.getAs<Decl>());
// If we don't have a valid method decl, simply return.
if (!MDecl)
@@ -53,11 +53,11 @@
PushOnScopeChains(*PI, FnBodyScope);
}
-Sema::DeclTy *Sema::
+Sema::DeclPtrTy Sema::
ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
IdentifierInfo *ClassName, SourceLocation ClassLoc,
IdentifierInfo *SuperName, SourceLocation SuperLoc,
- DeclTy * const *ProtoRefs, unsigned NumProtoRefs,
+ const DeclPtrTy *ProtoRefs, unsigned NumProtoRefs,
SourceLocation EndProtoLoc, AttributeList *AttrList) {
assert(ClassName && "Missing class identifier");
@@ -85,7 +85,7 @@
// Return the previous class interface.
// FIXME: don't leak the objects passed in!
- return IDecl;
+ return DeclPtrTy::make(IDecl);
} else {
IDecl->setLocation(AtInterfaceLoc);
IDecl->setForwardDecl(false);
@@ -100,7 +100,7 @@
// FIXME: PushOnScopeChains
CurContext->addDecl(IDecl);
// Remember that this needs to be removed when the scope is popped.
- TUScope->AddDecl(IDecl);
+ TUScope->AddDecl(DeclPtrTy::make(IDecl));
}
if (SuperName) {
@@ -160,16 +160,16 @@
}
CheckObjCDeclScope(IDecl);
- return IDecl;
+ return DeclPtrTy::make(IDecl);
}
/// ActOnCompatiblityAlias - this action is called after complete parsing of
/// @compatibility_alias declaration. It sets up the alias relationships.
-Sema::DeclTy *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
- IdentifierInfo *AliasName,
- SourceLocation AliasLocation,
- IdentifierInfo *ClassName,
- SourceLocation ClassLocation) {
+Sema::DeclPtrTy Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
+ IdentifierInfo *AliasName,
+ SourceLocation AliasLocation,
+ IdentifierInfo *ClassName,
+ SourceLocation ClassLocation) {
// Look for previous declaration of alias name
NamedDecl *ADecl = LookupName(TUScope, AliasName, LookupOrdinaryName);
if (ADecl) {
@@ -178,7 +178,7 @@
else
Diag(AliasLocation, diag::err_conflicting_aliasing_type) << AliasName;
Diag(ADecl->getLocation(), diag::note_previous_declaration);
- return 0;
+ return DeclPtrTy();
}
// Check for class declaration
NamedDecl *CDeclU = LookupName(TUScope, ClassName, LookupOrdinaryName);
@@ -196,7 +196,7 @@
Diag(ClassLocation, diag::warn_undef_interface) << ClassName;
if (CDeclU)
Diag(CDeclU->getLocation(), diag::note_previous_declaration);
- return 0;
+ return DeclPtrTy();
}
// Everything checked out, instantiate a new alias declaration AST.
@@ -208,9 +208,9 @@
// FIXME: PushOnScopeChains?
CurContext->addDecl(AliasDecl);
if (!CheckObjCDeclScope(AliasDecl))
- TUScope->AddDecl(AliasDecl);
+ TUScope->AddDecl(DeclPtrTy::make(AliasDecl));
- return AliasDecl;
+ return DeclPtrTy::make(AliasDecl);
}
void Sema::CheckForwardProtocolDeclarationForCircularDependency(
@@ -232,11 +232,11 @@
}
}
-Sema::DeclTy *
+Sema::DeclPtrTy
Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
IdentifierInfo *ProtocolName,
SourceLocation ProtocolLoc,
- DeclTy * const *ProtoRefs,
+ const DeclPtrTy *ProtoRefs,
unsigned NumProtoRefs,
SourceLocation EndProtoLoc,
AttributeList *AttrList) {
@@ -251,7 +251,7 @@
Diag(PDecl->getLocation(), diag::note_previous_definition);
// Just return the protocol we already had.
// FIXME: don't leak the objects passed in!
- return PDecl;
+ return DeclPtrTy::make(PDecl);
}
ObjCList<ObjCProtocolDecl> PList;
PList.set((ObjCProtocolDecl *const*)ProtoRefs, NumProtoRefs, Context);
@@ -279,7 +279,7 @@
}
CheckObjCDeclScope(PDecl);
- return PDecl;
+ return DeclPtrTy::make(PDecl);
}
/// FindProtocolDeclaration - This routine looks up protocols and
@@ -289,7 +289,7 @@
Sema::FindProtocolDeclaration(bool WarnOnDeclarations,
const IdentifierLocPair *ProtocolId,
unsigned NumProtocols,
- llvm::SmallVectorImpl<DeclTy*> &Protocols) {
+ llvm::SmallVectorImpl<DeclPtrTy> &Protocols) {
for (unsigned i = 0; i != NumProtocols; ++i) {
ObjCProtocolDecl *PDecl = ObjCProtocols[ProtocolId[i].first];
if (!PDecl) {
@@ -305,7 +305,7 @@
if (WarnOnDeclarations && PDecl->isForwardDecl())
Diag(ProtocolId[i].second, diag::warn_undef_protocolref)
<< ProtocolId[i].first;
- Protocols.push_back(PDecl);
+ Protocols.push_back(DeclPtrTy::make(PDecl));
}
}
@@ -428,8 +428,8 @@
/// inherited protocol into the list of properties for class/category 'CDecl'
///
void Sema::MergeProtocolPropertiesIntoClass(Decl *CDecl,
- DeclTy *MergeItsProtocols) {
- Decl *ClassDecl = static_cast<Decl *>(MergeItsProtocols);
+ DeclPtrTy MergeItsProtocols) {
+ Decl *ClassDecl = MergeItsProtocols.getAs<Decl>();
ObjCInterfaceDecl *IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(CDecl);
if (!IDecl) {
@@ -446,12 +446,12 @@
// their properties into this class as well.
for (ObjCCategoryDecl::protocol_iterator P = CatDecl->protocol_begin(),
E = CatDecl->protocol_end(); P != E; ++P)
- MergeProtocolPropertiesIntoClass(CatDecl, *P);
+ MergeProtocolPropertiesIntoClass(CatDecl, DeclPtrTy::make(*P));
} else {
ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl);
for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(),
E = MD->protocol_end(); P != E; ++P)
- MergeOneProtocolPropertiesIntoClass(CatDecl, (*P));
+ MergeOneProtocolPropertiesIntoClass(CatDecl, *P);
}
return;
}
@@ -466,12 +466,12 @@
// their properties into this class as well.
for (ObjCInterfaceDecl::protocol_iterator P = IDecl->protocol_begin(),
E = IDecl->protocol_end(); P != E; ++P)
- MergeProtocolPropertiesIntoClass(IDecl, *P);
+ MergeProtocolPropertiesIntoClass(IDecl, DeclPtrTy::make(*P));
} else {
ObjCProtocolDecl *MD = cast<ObjCProtocolDecl>(ClassDecl);
for (ObjCProtocolDecl::protocol_iterator P = MD->protocol_begin(),
E = MD->protocol_end(); P != E; ++P)
- MergeOneProtocolPropertiesIntoClass(IDecl, (*P));
+ MergeOneProtocolPropertiesIntoClass(IDecl, *P);
}
}
@@ -505,7 +505,7 @@
}
/// ActOnForwardProtocolDeclaration -
-Action::DeclTy *
+Action::DeclPtrTy
Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
const IdentifierLocPair *IdentList,
unsigned NumElts,
@@ -531,15 +531,15 @@
&Protocols[0], Protocols.size());
CurContext->addDecl(PDecl);
CheckObjCDeclScope(PDecl);
- return PDecl;
+ return DeclPtrTy::make(PDecl);
}
-Sema::DeclTy *Sema::
+Sema::DeclPtrTy Sema::
ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
IdentifierInfo *ClassName, SourceLocation ClassLoc,
IdentifierInfo *CategoryName,
SourceLocation CategoryLoc,
- DeclTy * const *ProtoRefs,
+ const DeclPtrTy *ProtoRefs,
unsigned NumProtoRefs,
SourceLocation EndProtoLoc) {
ObjCCategoryDecl *CDecl =
@@ -552,7 +552,7 @@
if (!IDecl || IDecl->isForwardDecl()) {
CDecl->setInvalidDecl();
Diag(ClassLoc, diag::err_undef_interface) << ClassName;
- return CDecl;
+ return DeclPtrTy::make(CDecl);
}
CDecl->setClassInterface(IDecl);
@@ -580,13 +580,13 @@
}
CheckObjCDeclScope(CDecl);
- return CDecl;
+ return DeclPtrTy::make(CDecl);
}
/// ActOnStartCategoryImplementation - Perform semantic checks on the
/// category implementation declaration and build an ObjCCategoryImplDecl
/// object.
-Sema::DeclTy *Sema::ActOnStartCategoryImplementation(
+Sema::DeclPtrTy Sema::ActOnStartCategoryImplementation(
SourceLocation AtCatImplLoc,
IdentifierInfo *ClassName, SourceLocation ClassLoc,
IdentifierInfo *CatName, SourceLocation CatLoc) {
@@ -606,10 +606,10 @@
ObjCCategoryImpls.push_back(CDecl);
CheckObjCDeclScope(CDecl);
- return CDecl;
+ return DeclPtrTy::make(CDecl);
}
-Sema::DeclTy *Sema::ActOnStartClassImplementation(
+Sema::DeclPtrTy Sema::ActOnStartClassImplementation(
SourceLocation AtClassImplLoc,
IdentifierInfo *ClassName, SourceLocation ClassLoc,
IdentifierInfo *SuperClassname,
@@ -666,7 +666,7 @@
// FIXME: PushOnScopeChains?
CurContext->addDecl(IDecl);
// Remember that this needs to be removed when the scope is popped.
- TUScope->AddDecl(IDecl);
+ TUScope->AddDecl(DeclPtrTy::make(IDecl));
}
ObjCImplementationDecl* IMPDecl =
@@ -677,7 +677,7 @@
CurContext->addDecl(IMPDecl);
if (CheckObjCDeclScope(IMPDecl))
- return IMPDecl;
+ return DeclPtrTy::make(IMPDecl);
// Check that there is no duplicate implementation of this class.
if (ObjCImplementations[ClassName])
@@ -685,7 +685,7 @@
Diag(ClassLoc, diag::err_dup_implementation_class) << ClassName;
else // add it to the list.
ObjCImplementations[ClassName] = IMPDecl;
- return IMPDecl;
+ return DeclPtrTy::make(IMPDecl);
}
void Sema::CheckImplementationIvars(ObjCImplementationDecl *ImpDecl,
@@ -957,7 +957,7 @@
}
/// ActOnForwardClassDeclaration -
-Action::DeclTy *
+Action::DeclPtrTy
Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
IdentifierInfo **IdentList,
unsigned NumElts) {
@@ -995,7 +995,7 @@
// FIXME: PushOnScopeChains?
CurContext->addDecl(IDecl);
// Remember that this needs to be removed when the scope is popped.
- TUScope->AddDecl(IDecl);
+ TUScope->AddDecl(DeclPtrTy::make(IDecl));
}
Interfaces.push_back(IDecl);
@@ -1006,7 +1006,7 @@
Interfaces.size());
CurContext->addDecl(CDecl);
CheckObjCDeclScope(CDecl);
- return CDecl;
+ return DeclPtrTy::make(CDecl);
}
@@ -1231,12 +1231,12 @@
// Note: For class/category implemenations, allMethods/allProperties is
// always null.
-void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
- DeclTy **allMethods, unsigned allNum,
- DeclTy **allProperties, unsigned pNum,
- DeclTy **allTUVars,
+void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclPtrTy classDecl,
+ DeclPtrTy *allMethods, unsigned allNum,
+ DeclPtrTy *allProperties, unsigned pNum,
+ DeclPtrTy *allTUVars,
unsigned tuvNum) {
- Decl *ClassDecl = static_cast<Decl *>(classDecl);
+ Decl *ClassDecl = classDecl.getAs<Decl>();
// FIXME: If we don't have a ClassDecl, we have an error. We should consider
// always passing in a decl. If the decl has an error, isInvalidDecl()
@@ -1257,7 +1257,7 @@
for (unsigned i = 0; i < allNum; i++ ) {
ObjCMethodDecl *Method =
- cast_or_null<ObjCMethodDecl>(static_cast<Decl*>(allMethods[i]));
+ cast_or_null<ObjCMethodDecl>(allMethods[i].getAs<Decl>());
if (!Method) continue; // Already issued a diagnostic.
if (Method->isInstanceMethod()) {
@@ -1299,14 +1299,14 @@
// Compares properties declared in this class to those of its
// super class.
ComparePropertiesInBaseAndSuper(I);
- MergeProtocolPropertiesIntoClass(I, I);
+ MergeProtocolPropertiesIntoClass(I, DeclPtrTy::make(I));
} else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
// Categories are used to extend the class by declaring new methods.
// By the same token, they are also used to add new properties. No
// need to compare the added property to those in the class.
// Merge protocol properties into category
- MergeProtocolPropertiesIntoClass(C, C);
+ MergeProtocolPropertiesIntoClass(C, DeclPtrTy::make(C));
if (C->getIdentifier() == 0)
DiagnoseClassExtensionDupMethods(C, C->getClassInterface());
}
@@ -1341,7 +1341,7 @@
}
if (isInterfaceDeclKind)
for (unsigned i = 0; i < tuvNum; i++) {
- if (VarDecl *VDecl = dyn_cast<VarDecl>((Decl*)allTUVars[i])) {
+ if (VarDecl *VDecl = dyn_cast<VarDecl>(allTUVars[i].getAs<Decl>())) {
if (VDecl->getStorageClass() != VarDecl::Extern &&
VDecl->getStorageClass() != VarDecl::PrivateExtern) {
NamedDecl *ClassNameDecl = dyn_cast<NamedDecl>(ClassDecl);
@@ -1374,9 +1374,9 @@
return ret;
}
-Sema::DeclTy *Sema::ActOnMethodDeclaration(
+Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
SourceLocation MethodLoc, SourceLocation EndLoc,
- tok::TokenKind MethodType, DeclTy *classDecl,
+ tok::TokenKind MethodType, DeclPtrTy classDecl,
ObjCDeclSpec &ReturnQT, TypeTy *ReturnType,
Selector Sel,
// optional arguments. The number of types/arguments is obtained
@@ -1385,12 +1385,12 @@
llvm::SmallVectorImpl<Declarator> &Cdecls,
AttributeList *AttrList, tok::ObjCKeywordKind MethodDeclKind,
bool isVariadic) {
- Decl *ClassDecl = static_cast<Decl*>(classDecl);
+ Decl *ClassDecl = classDecl.getAs<Decl>();
// Make sure we can establish a context for the method.
if (!ClassDecl) {
Diag(MethodLoc, diag::error_missing_method_context);
- return 0;
+ return DeclPtrTy();
}
QualType resultDeclType;
@@ -1402,7 +1402,7 @@
if (resultDeclType->isObjCInterfaceType()) {
Diag(MethodLoc, diag::err_object_cannot_be_by_value)
<< "returned";
- return 0;
+ return DeclPtrTy();
}
} else // get the type for "id".
resultDeclType = Context.getObjCIdType();
@@ -1436,7 +1436,7 @@
Diag(MethodLoc, diag::err_object_cannot_be_by_value)
<< "passed";
ObjCMethod->setInvalidDecl();
- return 0;
+ return DeclPtrTy();
}
} else
argType = Context.getObjCIdType();
@@ -1495,7 +1495,7 @@
<< ObjCMethod->getDeclName();
Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
}
- return ObjCMethod;
+ return DeclPtrTy::make(ObjCMethod);
}
void Sema::CheckObjCPropertyAttributes(QualType PropertyTy,
@@ -1571,14 +1571,14 @@
}
}
-Sema::DeclTy *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
- FieldDeclarator &FD,
- ObjCDeclSpec &ODS,
- Selector GetterSel,
- Selector SetterSel,
- DeclTy *ClassCategory,
- bool *isOverridingProperty,
- tok::ObjCKeywordKind MethodImplKind) {
+Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
+ FieldDeclarator &FD,
+ ObjCDeclSpec &ODS,
+ Selector GetterSel,
+ Selector SetterSel,
+ DeclPtrTy ClassCategory,
+ bool *isOverridingProperty,
+ tok::ObjCKeywordKind MethodImplKind) {
unsigned Attributes = ODS.getPropertyAttributes();
bool isReadWrite = ((Attributes & ObjCDeclSpec::DQ_PR_readwrite) ||
// default is readwrite!
@@ -1590,7 +1590,7 @@
!(Attributes & ObjCDeclSpec::DQ_PR_retain) &&
!(Attributes & ObjCDeclSpec::DQ_PR_copy)));
QualType T = GetTypeForDeclarator(FD.D, S);
- Decl *ClassDecl = static_cast<Decl *>(ClassCategory);
+ Decl *ClassDecl = ClassCategory.getAs<Decl>();
// May modify Attributes.
CheckObjCPropertyAttributes(T, AtLoc, Attributes);
@@ -1632,7 +1632,7 @@
else
Diag(AtLoc, diag::err_use_continuation_class) << ICDecl->getDeclName();
*isOverridingProperty = true;
- return 0;
+ return DeclPtrTy();
}
// No matching property found in the main class. Just fall thru
// and add property to the anonymous category. It looks like
@@ -1641,7 +1641,7 @@
} else {
Diag(CDecl->getLocation(), diag::err_continuation_class);
*isOverridingProperty = true;
- return 0;
+ return DeclPtrTy();
}
}
@@ -1691,24 +1691,24 @@
else if (MethodImplKind == tok::objc_optional)
PDecl->setPropertyImplementation(ObjCPropertyDecl::Optional);
- return PDecl;
+ return DeclPtrTy::make(PDecl);
}
/// ActOnPropertyImplDecl - This routine performs semantic checks and
/// builds the AST node for a property implementation declaration; declared
/// as @synthesize or @dynamic.
///
-Sema::DeclTy *Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
- SourceLocation PropertyLoc,
- bool Synthesize,
- DeclTy *ClassCatImpDecl,
- IdentifierInfo *PropertyId,
- IdentifierInfo *PropertyIvar) {
- Decl *ClassImpDecl = static_cast<Decl*>(ClassCatImpDecl);
+Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
+ SourceLocation PropertyLoc,
+ bool Synthesize,
+ DeclPtrTy ClassCatImpDecl,
+ IdentifierInfo *PropertyId,
+ IdentifierInfo *PropertyIvar) {
+ Decl *ClassImpDecl = ClassCatImpDecl.getAs<Decl>();
// Make sure we have a context for the property implementation declaration.
if (!ClassImpDecl) {
Diag(AtLoc, diag::error_missing_property_context);
- return 0;
+ return DeclPtrTy();
}
ObjCPropertyDecl *property = 0;
ObjCInterfaceDecl* IDecl = 0;
@@ -1727,18 +1727,18 @@
property = IDecl->FindPropertyDeclaration(PropertyId);
if (!property) {
Diag(PropertyLoc, diag::error_bad_property_decl) << IDecl->getDeclName();
- return 0;
+ return DeclPtrTy();
}
}
else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) {
if (Synthesize) {
Diag(AtLoc, diag::error_synthesize_category_decl);
- return 0;
+ return DeclPtrTy();
}
IDecl = CatImplClass->getClassInterface();
if (!IDecl) {
Diag(AtLoc, diag::error_missing_property_interface);
- return 0;
+ return DeclPtrTy();
}
ObjCCategoryDecl *Category =
IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier());
@@ -1746,18 +1746,17 @@
// If category for this implementation not found, it is an error which
// has already been reported eralier.
if (!Category)
- return 0;
+ return DeclPtrTy();
// Look for this property declaration in @implementation's category
property = Category->FindPropertyDeclaration(PropertyId);
if (!property) {
Diag(PropertyLoc, diag::error_bad_category_property_decl)
<< Category->getDeclName();
- return 0;
+ return DeclPtrTy();
}
- }
- else {
+ } else {
Diag(AtLoc, diag::error_bad_property_context);
- return 0;
+ return DeclPtrTy();
}
ObjCIvarDecl *Ivar = 0;
// Check that we have a valid, previously declared ivar for @synthesize
@@ -1773,7 +1772,7 @@
<< PropertyId;
else
Diag(PropertyLoc, diag::error_missing_property_ivar_decl) << PropertyId;
- return 0;
+ return DeclPtrTy();
}
QualType PropType = Context.getCanonicalType(property->getType());
QualType IvarType = Context.getCanonicalType(Ivar->getType());
@@ -1783,40 +1782,37 @@
if (CheckAssignmentConstraints(PropType, IvarType) != Compatible) {
Diag(PropertyLoc, diag::error_property_ivar_type)
<< property->getDeclName() << Ivar->getDeclName();
- return 0;
+ return DeclPtrTy();
}
- else {
- // FIXME! Rules for properties are somewhat different that those
- // for assignments. Use a new routine to consolidate all cases;
- // specifically for property redeclarations as well as for ivars.
- QualType lhsType =
- Context.getCanonicalType(PropType).getUnqualifiedType();
- QualType rhsType =
- Context.getCanonicalType(IvarType).getUnqualifiedType();
- if (lhsType != rhsType &&
- lhsType->isArithmeticType()) {
- Diag(PropertyLoc, diag::error_property_ivar_type)
- << property->getDeclName() << Ivar->getDeclName();
- return 0;
- }
- // __weak is explicit. So it works on Canonical type.
- if (PropType.isObjCGCWeak() && !IvarType.isObjCGCWeak()) {
- Diag(PropertyLoc, diag::error_weak_property)
- << property->getDeclName() << Ivar->getDeclName();
- return 0;
- }
- if ((Context.isObjCObjectPointerType(property->getType()) ||
- PropType.isObjCGCStrong()) && IvarType.isObjCGCWeak()) {
- Diag(PropertyLoc, diag::error_strong_property)
- << property->getDeclName() << Ivar->getDeclName();
- return 0;
- }
+
+ // FIXME! Rules for properties are somewhat different that those
+ // for assignments. Use a new routine to consolidate all cases;
+ // specifically for property redeclarations as well as for ivars.
+ QualType lhsType =Context.getCanonicalType(PropType).getUnqualifiedType();
+ QualType rhsType =Context.getCanonicalType(IvarType).getUnqualifiedType();
+ if (lhsType != rhsType &&
+ lhsType->isArithmeticType()) {
+ Diag(PropertyLoc, diag::error_property_ivar_type)
+ << property->getDeclName() << Ivar->getDeclName();
+ return DeclPtrTy();
+ }
+ // __weak is explicit. So it works on Canonical type.
+ if (PropType.isObjCGCWeak() && !IvarType.isObjCGCWeak()) {
+ Diag(PropertyLoc, diag::error_weak_property)
+ << property->getDeclName() << Ivar->getDeclName();
+ return DeclPtrTy();
+ }
+ if ((Context.isObjCObjectPointerType(property->getType()) ||
+ PropType.isObjCGCStrong()) && IvarType.isObjCGCWeak()) {
+ Diag(PropertyLoc, diag::error_strong_property)
+ << property->getDeclName() << Ivar->getDeclName();
+ return DeclPtrTy();
}
}
} else if (PropertyIvar) {
// @dynamic
Diag(PropertyLoc, diag::error_dynamic_property_ivar_decl);
- return 0;
+ return DeclPtrTy();
}
assert (property && "ActOnPropertyImplDecl - property declaration missing");
ObjCPropertyImplDecl *PIDecl =
@@ -1840,7 +1836,7 @@
if (ObjCPropertyImplDecl *PPIDecl = IC->FindPropertyImplDecl(PropertyId)) {
Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
- return 0;
+ return DeclPtrTy();
}
IC->addPropertyImplementation(PIDecl);
}
@@ -1858,12 +1854,12 @@
CatImplClass->FindPropertyImplDecl(PropertyId)) {
Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
- return 0;
+ return DeclPtrTy();
}
CatImplClass->addPropertyImplementation(PIDecl);
}
- return PIDecl;
+ return DeclPtrTy::make(PIDecl);
}
bool Sema::CheckObjCDeclScope(Decl *D) {
@@ -1882,28 +1878,26 @@
/// part of the AST generation logic of @defs.
static void CollectIvars(ObjCInterfaceDecl *Class, RecordDecl *Record,
ASTContext& Ctx,
- llvm::SmallVectorImpl<Sema::DeclTy*> &ivars) {
+ llvm::SmallVectorImpl<Sema::DeclPtrTy> &ivars) {
if (Class->getSuperClass())
CollectIvars(Class->getSuperClass(), Record, Ctx, ivars);
// For each ivar, create a fresh ObjCAtDefsFieldDecl.
- for (ObjCInterfaceDecl::ivar_iterator
- I=Class->ivar_begin(), E=Class->ivar_end(); I!=E; ++I) {
-
+ for (ObjCInterfaceDecl::ivar_iterator I = Class->ivar_begin(),
+ E = Class->ivar_end(); I != E; ++I) {
ObjCIvarDecl* ID = *I;
- ivars.push_back(ObjCAtDefsFieldDecl::Create(Ctx, Record,
- ID->getLocation(),
- ID->getIdentifier(),
- ID->getType(),
- ID->getBitWidth()));
+ Decl *FD = ObjCAtDefsFieldDecl::Create(Ctx, Record, ID->getLocation(),
+ ID->getIdentifier(), ID->getType(),
+ ID->getBitWidth());
+ ivars.push_back(Sema::DeclPtrTy::make(FD));
}
}
/// Called whenever @defs(ClassName) is encountered in the source. Inserts the
/// instance variables of ClassName into Decls.
-void Sema::ActOnDefs(Scope *S, DeclTy *TagD, SourceLocation DeclStart,
+void Sema::ActOnDefs(Scope *S, DeclPtrTy TagD, SourceLocation DeclStart,
IdentifierInfo *ClassName,
- llvm::SmallVectorImpl<DeclTy*> &Decls) {
+ llvm::SmallVectorImpl<DeclPtrTy> &Decls) {
// Check that ClassName is a valid class
ObjCInterfaceDecl *Class = getObjCInterfaceDecl(ClassName);
if (!Class) {
@@ -1911,15 +1905,15 @@
return;
}
// Collect the instance variables
- CollectIvars(Class, dyn_cast<RecordDecl>((Decl*)TagD), Context, Decls);
+ CollectIvars(Class, dyn_cast<RecordDecl>(TagD.getAs<Decl>()), Context, Decls);
// Introduce all of these fields into the appropriate scope.
- for (llvm::SmallVectorImpl<DeclTy*>::iterator D = Decls.begin();
+ for (llvm::SmallVectorImpl<DeclPtrTy>::iterator D = Decls.begin();
D != Decls.end(); ++D) {
- FieldDecl *FD = cast<FieldDecl>((Decl*)*D);
+ FieldDecl *FD = cast<FieldDecl>(D->getAs<Decl>());
if (getLangOptions().CPlusPlus)
PushOnScopeChains(cast<FieldDecl>(FD), S);
- else if (RecordDecl *Record = dyn_cast<RecordDecl>((Decl*)TagD))
+ else if (RecordDecl *Record = dyn_cast<RecordDecl>(TagD.getAs<Decl>()))
Record->addDecl(FD);
}
}