]> granicus.if.org Git - clang/commitdiff
Make it an error if an Objective-C declaration is not in the global scope.
authorAnders Carlsson <andersca@mac.com>
Tue, 4 Nov 2008 16:57:32 +0000 (16:57 +0000)
committerAnders Carlsson <andersca@mac.com>
Tue, 4 Nov 2008 16:57:32 +0000 (16:57 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58705 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticKinds.def
lib/Sema/Sema.h
lib/Sema/SemaDeclObjC.cpp
test/SemaObjCXX/objc-decls-inside-namespace.mm [new file with mode: 0644]

index 32f52f41cbc5d192d6ae54ea9d5765df0ca41dc4..8517222c1db48c9f34521a83cae2aabadb70ac17 100644 (file)
@@ -696,6 +696,10 @@ DIAG(err_reference_var_requires_init, ERROR,
 DIAG(err_const_var_requires_init, ERROR,
      "declaration of const variable '%0' requires an initializer")
 
+// Objective-C++
+DIAG(err_objc_decls_may_only_appear_in_global_scope, ERROR,
+     "Objective-C declarations may only appear in global scope")
+
 // Attributes
 DIAG(err_attribute_wrong_number_arguments, ERROR,
      "attribute requires %0 argument(s)")
index a3d73c4c9311ed235b234a31d5359d0e0ce0b098..ce70855a3784300f36c721605405343f3c21ce53 100644 (file)
@@ -1209,7 +1209,11 @@ private:
   bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS,
                                          bool ForCompare);
 
-  
+  /// Checks that the Objective-C declaration is declared in the global scope.
+  /// Emits an error and marks the declaration as invalid if it's not declared
+  /// in the global scope.
+  bool CheckObjCDeclScope(Decl *D);
+
   void InitBuiltinVaListType();
 
   // Helper method to turn variable array types into
index 3ccea6e08207869c4aeb1f5ba35e2c38830a7c9a..6c17d5f1f6c917c8f06ef3fe238dbe132cd59c33 100644 (file)
@@ -124,6 +124,8 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
     IDecl->addReferencedProtocols((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs);
     IDecl->setLocEnd(EndProtoLoc);
   }
+  
+  CheckObjCDeclScope(IDecl);
   return IDecl;
 }
 
@@ -163,7 +165,10 @@ Sema::DeclTy *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
     ObjCCompatibleAliasDecl::Create(Context, AtLoc, AliasName, CDecl);
   
   ObjCAliasDecls[AliasName] = AliasDecl;
-  TUScope->AddDecl(AliasDecl);
+  
+  if (!CheckObjCDeclScope(AliasDecl))
+    TUScope->AddDecl(AliasDecl);
+  
   return AliasDecl;
 }
 
@@ -201,6 +206,8 @@ Sema::ActOnStartProtocolInterface(SourceLocation AtProtoInterfaceLoc,
     PDecl->addReferencedProtocols((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs);
     PDecl->setLocEnd(EndProtoLoc);
   }
+  
+  CheckObjCDeclScope(PDecl);  
   return PDecl;
 }
 
@@ -370,8 +377,13 @@ Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
     
     Protocols.push_back(PDecl);
   }
-  return ObjCForwardProtocolDecl::Create(Context, AtProtocolLoc,
-                                         &Protocols[0], Protocols.size());
+  
+  ObjCForwardProtocolDecl *PDecl = 
+    ObjCForwardProtocolDecl::Create(Context, AtProtocolLoc,
+                                    &Protocols[0], Protocols.size());
+  
+  CheckObjCDeclScope(PDecl);
+  return PDecl;
 }
 
 Sema::DeclTy *Sema::
@@ -410,6 +422,8 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
     CDecl->addReferencedProtocols((ObjCProtocolDecl**)ProtoRefs, NumProtoRefs);
     CDecl->setLocEnd(EndProtoLoc);
   }
+  
+  CheckObjCDeclScope(CDecl);
   return CDecl;
 }
 
@@ -430,6 +444,8 @@ Sema::DeclTy *Sema::ActOnStartCategoryImplementation(
   /// TODO: Check that CatName, category name, is not used in another
   // implementation.
   ObjCCategoryImpls.push_back(CDecl);
+  
+  CheckObjCDeclScope(CDecl);
   return CDecl;
 }
 
@@ -498,6 +514,9 @@ Sema::DeclTy *Sema::ActOnStartClassImplementation(
     ObjCImplementationDecl::Create(Context, AtClassImplLoc, ClassName, 
                                    IDecl, SDecl);
   
+  if (CheckObjCDeclScope(IMPDecl))
+    return IMPDecl;
+  
   // Check that there is no duplicate implementation of this class.
   if (ObjCImplementations[ClassName])
     // FIXME: Don't leak everything!
@@ -730,8 +749,12 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
     Interfaces.push_back(IDecl);
   }
   
-  return ObjCClassDecl::Create(Context, AtClassLoc,
-                               &Interfaces[0], Interfaces.size());
+  ObjCClassDecl *CDecl = ObjCClassDecl::Create(Context, AtClassLoc,
+                                               &Interfaces[0],
+                                               Interfaces.size());
+  
+  CheckObjCDeclScope(CDecl);
+  return CDecl;  
 }
 
 
@@ -1327,3 +1350,14 @@ Sema::DeclTy *Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
     
   return PIDecl;
 }
+
+bool Sema::CheckObjCDeclScope(Decl *D)
+{
+  if (isa<TranslationUnitDecl>(CurContext))
+    return false;
+  
+  Diag(D->getLocation(), diag::err_objc_decls_may_only_appear_in_global_scope);
+  D->setInvalidDecl();
+  
+  return true;
+}
diff --git a/test/SemaObjCXX/objc-decls-inside-namespace.mm b/test/SemaObjCXX/objc-decls-inside-namespace.mm
new file mode 100644 (file)
index 0000000..3ad3508
--- /dev/null
@@ -0,0 +1,27 @@
+// RUN: clang -fsyntax-only -verify %s
+
+namespace C {
+
+@protocol P; //expected-error{{Objective-C declarations may only appear in global scope}}
+
+@class Bar; //expected-error{{Objective-C declarations may only appear in global scope}}
+
+@compatibility_alias Foo Bar; //expected-error{{Objective-C declarations may only appear in global scope}}
+
+@interface A //expected-error{{Objective-C declarations may only appear in global scope}}
+@end
+
+@implementation A //expected-error{{Objective-C declarations may only appear in global scope}}
+@end
+
+@protocol P //expected-error{{Objective-C declarations may only appear in global scope}}
+@end
+
+@interface A(C) //expected-error{{Objective-C declarations may only appear in global scope}}
+@end
+
+@implementation A(C) //expected-error{{Objective-C declarations may only appear in global scope}}
+@end
+
+}
+