Issue error if variables are defined inside an objc class,

category or protocol.

llvm-svn: 67450
This commit is contained in:
Fariborz Jahanian 2009-03-21 18:06:45 +00:00
parent 891d57155e
commit 629aed9327
7 changed files with 39 additions and 57 deletions

View File

@ -246,11 +246,6 @@ public:
/// ///
class ObjCContainerDecl : public NamedDecl, public DeclContext { class ObjCContainerDecl : public NamedDecl, public DeclContext {
SourceLocation AtEndLoc; // marks the end of the method container. SourceLocation AtEndLoc; // marks the end of the method container.
// FIXME. In the long term, all TU variables declared in class scope belong
// to class's decl context. This waits till we can establish class's
// context before processing all decls in the class.
/// Instance variables in the interface.
ObjCList<VarDecl> TUVars;
public: public:
ObjCContainerDecl(Kind DK, DeclContext *DC, SourceLocation L, ObjCContainerDecl(Kind DK, DeclContext *DC, SourceLocation L,
@ -303,15 +298,7 @@ public:
ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const { ObjCMethodDecl *getMethod(Selector Sel, bool isInstance) const {
return isInstance ? getInstanceMethod(Sel) : getClassMethod(Sel); return isInstance ? getInstanceMethod(Sel) : getClassMethod(Sel);
} }
typedef ObjCList<VarDecl>::iterator tuvar_iterator;
tuvar_iterator tuvar_begin() const { return TUVars.begin(); }
tuvar_iterator tuvar_end() const { return TUVars.end(); }
unsigned tuvar_size() const { return TUVars.size(); }
void setTUVarList(VarDecl * const *List, unsigned Num, ASTContext &C) {
TUVars.set(List, Num, C);
}
ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const; ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const;
// Marks the end of the container. // Marks the end of the container.

View File

@ -1025,6 +1025,8 @@ DIAG(err_illegal_qualifiers_on_catch_parm, ERROR,
"illegal qualifiers on @catch parameter") "illegal qualifiers on @catch parameter")
DIAG(err_illegal_super_cast, ERROR, DIAG(err_illegal_super_cast, ERROR,
"cannot cast 'super' (it isn't an expression)") "cannot cast 'super' (it isn't an expression)")
DIAG(err_objc_var_decl_inclass, ERROR,
"cannot declare variable inside a class, protocol or category %0")
// C++ casts // C++ casts

View File

@ -161,6 +161,8 @@ def err_accessor_property_type_mismatch : Error<
def note_declared_at : Note<"declared at">; def note_declared_at : Note<"declared at">;
def err_setter_type_void : Error<"type of setter must be void">; def err_setter_type_void : Error<"type of setter must be void">;
def err_duplicate_method_decl : Error<"duplicate declaration of method %0">; def err_duplicate_method_decl : Error<"duplicate declaration of method %0">;
def err_objc_var_decl_inclass :
Error<"cannot declare variable inside a class, protocol or category %0">;
def error_missing_method_context : Error< def error_missing_method_context : Error<
"missing context for method declaration">; "missing context for method declaration">;
def err_objc_property_attr_mutually_exclusive : Error< def err_objc_property_attr_mutually_exclusive : Error<

View File

@ -1270,21 +1270,13 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
// Forward declarations, no (immediate) code generation. // Forward declarations, no (immediate) code generation.
case Decl::ObjCClass: case Decl::ObjCClass:
case Decl::ObjCForwardProtocol: case Decl::ObjCForwardProtocol:
case Decl::ObjCCategory:
case Decl::ObjCInterface:
break; break;
case Decl::ObjCProtocol: case Decl::ObjCProtocol:
case Decl::ObjCCategory: Runtime->GenerateProtocol(cast<ObjCProtocolDecl>(D));
case Decl::ObjCInterface: {
ObjCContainerDecl *OCD = cast<ObjCContainerDecl>(D);
for (ObjCContainerDecl::tuvar_iterator i = OCD->tuvar_begin(),
e = OCD->tuvar_end(); i != e; ++i) {
VarDecl *VD = *i;
EmitGlobal(VD);
}
if (D->getKind() == Decl::ObjCProtocol)
Runtime->GenerateProtocol(cast<ObjCProtocolDecl>(D));
break; break;
}
case Decl::ObjCCategoryImpl: case Decl::ObjCCategoryImpl:
// Categories have properties but don't support synthesize so we // Categories have properties but don't support synthesize so we

View File

@ -1339,14 +1339,16 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
} }
} }
} }
llvm::SmallVector<VarDecl*, 8> allTUVariables; if (isInterfaceDeclKind)
for (unsigned i = 0; i < tuvNum; i++) { for (unsigned i = 0; i < tuvNum; i++) {
if (VarDecl *VD = dyn_cast<VarDecl>((Decl*)allTUVars[i])) if (VarDecl *VDecl = dyn_cast<VarDecl>((Decl*)allTUVars[i])) {
allTUVariables.push_back(VD); if (VDecl->getStorageClass() != VarDecl::Extern &&
} VDecl->getStorageClass() != VarDecl::PrivateExtern) {
if (!allTUVariables.empty() && isInterfaceDeclKind) { NamedDecl *ClassNameDecl = dyn_cast<NamedDecl>(ClassDecl);
ObjCContainerDecl *OCD = dyn_cast<ObjCContainerDecl>(ClassDecl); Diag(VDecl->getLocation(), diag::err_objc_var_decl_inclass)
OCD->setTUVarList(&allTUVariables[0], allTUVariables.size(), Context); << ClassNameDecl->getIdentifier();
}
}
} }
} }

View File

@ -1,24 +0,0 @@
// RUN: clang -fnext-runtime -emit-llvm -o %t %s
// RUN: grep 'two = global' %t &&
// RUN: grep 'ddd = common' %t &&
// RUN: grep 'III = common' %t
@interface XX
int x;
int one=1;
int two = 2;
@end
@protocol PPP
int ddd;
@end
@interface XX(CAT)
char * III;
@end
int main( int argc, const char *argv[] ) {
return x+one+two;
}

View File

@ -0,0 +1,21 @@
// RUN: clang -fsyntax-only -verify %s
@interface XX
int x; // expected-error {{cannot declare variable inside a class, protocol or category}}
int one=1; // expected-error {{cannot declare variable inside a class, protocol or category}}
@end
@protocol PPP
int ddd; // expected-error {{cannot declare variable inside a class, protocol or category}}
@end
@interface XX(CAT)
char * III; // expected-error {{cannot declare variable inside a class, protocol or category}}
extern int OK;
@end
int main( int argc, const char *argv[] ) {
return x+one;
}