]> granicus.if.org Git - clang/commitdiff
Allow Objective-C entities to be declared within a transparent context
authorDouglas Gregor <dgregor@apple.com>
Tue, 6 Jan 2009 23:51:29 +0000 (23:51 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 6 Jan 2009 23:51:29 +0000 (23:51 +0000)
nested in the translation unit. This fixes <rdar://problem/6476070>.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61832 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/DeclBase.h
lib/AST/DeclBase.cpp
lib/Sema/IdentifierResolver.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclObjC.cpp
test/SemaObjCXX/linkage-spec.mm [new file with mode: 0644]

index fac0668efd3ad79800c6e0d4bbc931ad728c5581..119db2ee21b2fa7d0730c56e5e302f51336b0216 100644 (file)
@@ -425,6 +425,12 @@ public:
   /// information needed to perform name lookup into this context.
   DeclContext *getPrimaryContext(ASTContext &Context);
 
+  /// getLookupContext - Retrieve the innermost non-transparent
+  /// context of this context, which corresponds to the innermost
+  /// location from which name lookup can find the entities in this
+  /// context.
+  DeclContext *getLookupContext();
+
   /// getNextContext - If this is a DeclContext that may have other
   /// DeclContexts that are semantically connected but syntactically
   /// different, such as C++ namespaces, this routine retrieves the
index a21d5db11a34813a87c3ef4abdd9a8f57f778b5c..faaa1045ded18cc96c285435ae744cc1155902e5 100644 (file)
@@ -567,6 +567,13 @@ DeclContext::lookup(ASTContext &Context, DeclarationName Name) const {
   return const_cast<DeclContext*>(this)->lookup(Context, Name);
 }
 
+DeclContext *DeclContext::getLookupContext() {
+  DeclContext *Ctx = this;
+  while (Ctx->isTransparentContext())
+    Ctx = Ctx->getParent();
+  return Ctx;
+}
+
 void DeclContext::insert(ASTContext &Context, ScopedDecl *D) {
   DeclContext *PrimaryContext = getPrimaryContext(Context);
   if (PrimaryContext != this) {
index 18e78a0d1703be11f7b567ffa55a335aee52da03..08c9bdeb3197dfe7a82d094c78580ff268cd332d 100644 (file)
@@ -60,8 +60,7 @@ DeclContext *IdentifierResolver::LookupContext::getContext(Decl *D) {
   else
     return TUCtx();
 
-  while (Ctx->isTransparentContext())
-    Ctx = Ctx->getParent();
+  Ctx = Ctx->getLookupContext();
 
   if (isa<TranslationUnitDecl>(Ctx))
     return TUCtx();
@@ -132,8 +131,7 @@ IdentifierResolver::~IdentifierResolver() {
 /// true if 'D' belongs to the given declaration context.
 bool IdentifierResolver::isDeclInScope(Decl *D, DeclContext *Ctx,
                                        ASTContext &Context, Scope *S) const {
-  while (Ctx->isTransparentContext())
-    Ctx = Ctx->getParent();
+  Ctx = Ctx->getLookupContext();
 
   if (Ctx->isFunctionOrMethod()) {
     // Ignore the scopes associated within transparent declaration contexts.
index 0e14150021e696e4aeb35d3e9307e88daa2d37d3..79e443d0b44232ee1d4293889e2ffd95f4df0b46 100644 (file)
@@ -156,9 +156,7 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S) {
     // We are pushing the name of a function, which might be an
     // overloaded name.
     FunctionDecl *FD = cast<FunctionDecl>(D);
-    DeclContext *DC = FD->getDeclContext();                                     
-    while (DC->isTransparentContext())
-      DC = DC->getParent(); 
+    DeclContext *DC = FD->getDeclContext()->getLookupContext();
     IdentifierResolver::iterator Redecl
       = std::find_if(IdResolver.begin(FD->getDeclName(), DC, 
                                       false/*LookInParentCtx*/),
index cf1a5259f20c0277c67caa7a0a7540c7be93d72c..c32a806b7d1a5f9f0e00af5a7115784d9ef46bfc 100644 (file)
@@ -1647,7 +1647,7 @@ Sema::DeclTy *Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
 }
 
 bool Sema::CheckObjCDeclScope(Decl *D) {
-  if (isa<TranslationUnitDecl>(CurContext))
+  if (isa<TranslationUnitDecl>(CurContext->getLookupContext()))
     return false;
   
   Diag(D->getLocation(), diag::err_objc_decls_may_only_appear_in_global_scope);
diff --git a/test/SemaObjCXX/linkage-spec.mm b/test/SemaObjCXX/linkage-spec.mm
new file mode 100644 (file)
index 0000000..c8221d4
--- /dev/null
@@ -0,0 +1,4 @@
+// RUN: clang -fsyntax-only -verify %s
+extern "C" {
+@class Protocol;
+}