summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-01-06 23:51:29 +0000
committerDouglas Gregor <dgregor@apple.com>2009-01-06 23:51:29 +0000
commit6ad0ef50918ed9cefff5fefb37d4f6dc2fac2343 (patch)
tree56e7cd61b0d1d20a40f4edb5097519c9e3af9537
parent44a3da6c4dc98e9303c07836257ced0bc4a12cbb (diff)
downloadbcm5719-llvm-6ad0ef50918ed9cefff5fefb37d4f6dc2fac2343.tar.gz
bcm5719-llvm-6ad0ef50918ed9cefff5fefb37d4f6dc2fac2343.zip
Allow Objective-C entities to be declared within a transparent context
nested in the translation unit. This fixes <rdar://problem/6476070>. llvm-svn: 61832
-rw-r--r--clang/include/clang/AST/DeclBase.h6
-rw-r--r--clang/lib/AST/DeclBase.cpp7
-rw-r--r--clang/lib/Sema/IdentifierResolver.cpp6
-rw-r--r--clang/lib/Sema/SemaDecl.cpp4
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp2
-rw-r--r--clang/test/SemaObjCXX/linkage-spec.mm4
6 files changed, 21 insertions, 8 deletions
diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h
index fac0668efd3..119db2ee21b 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -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
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index a21d5db11a3..faaa1045ded 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -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) {
diff --git a/clang/lib/Sema/IdentifierResolver.cpp b/clang/lib/Sema/IdentifierResolver.cpp
index 18e78a0d170..08c9bdeb319 100644
--- a/clang/lib/Sema/IdentifierResolver.cpp
+++ b/clang/lib/Sema/IdentifierResolver.cpp
@@ -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.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 0e14150021e..79e443d0b44 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -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*/),
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index cf1a5259f20..c32a806b7d1 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -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/clang/test/SemaObjCXX/linkage-spec.mm b/clang/test/SemaObjCXX/linkage-spec.mm
new file mode 100644
index 00000000000..c8221d470ee
--- /dev/null
+++ b/clang/test/SemaObjCXX/linkage-spec.mm
@@ -0,0 +1,4 @@
+// RUN: clang -fsyntax-only -verify %s
+extern "C" {
+@class Protocol;
+}
OpenPOWER on IntegriCloud