diff options
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 27 | ||||
-rw-r--r-- | test/SemaCXX/linkage-spec.cpp | 7 |
2 files changed, 23 insertions, 11 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 8e1a19cbe5..cfea66bf5a 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1839,17 +1839,22 @@ Sema::HandleDeclarator(Scope *S, Declarator &D, if (isa<TranslationUnitDecl>(DC)) { Diag(D.getIdentifierLoc(), diag::err_invalid_declarator_global_scope) << Name << D.getCXXScopeSpec().getRange(); - } else if (!CurContext->Encloses(DC)) { - // The qualifying scope doesn't enclose the original declaration. - // Emit diagnostic based on current scope. - SourceLocation L = D.getIdentifierLoc(); - SourceRange R = D.getCXXScopeSpec().getRange(); - if (isa<FunctionDecl>(CurContext)) - Diag(L, diag::err_invalid_declarator_in_function) << Name << R; - else - Diag(L, diag::err_invalid_declarator_scope) - << Name << cast<NamedDecl>(DC) << R; - D.setInvalidType(); + } else { + DeclContext *Cur = CurContext; + while (isa<LinkageSpecDecl>(Cur)) + Cur = Cur->getParent(); + if (!Cur->Encloses(DC)) { + // The qualifying scope doesn't enclose the original declaration. + // Emit diagnostic based on current scope. + SourceLocation L = D.getIdentifierLoc(); + SourceRange R = D.getCXXScopeSpec().getRange(); + if (isa<FunctionDecl>(Cur)) + Diag(L, diag::err_invalid_declarator_in_function) << Name << R; + else + Diag(L, diag::err_invalid_declarator_scope) + << Name << cast<NamedDecl>(DC) << R; + D.setInvalidType(); + } } } diff --git a/test/SemaCXX/linkage-spec.cpp b/test/SemaCXX/linkage-spec.cpp index 53cd61c7f5..fc9b3ab51e 100644 --- a/test/SemaCXX/linkage-spec.cpp +++ b/test/SemaCXX/linkage-spec.cpp @@ -33,3 +33,10 @@ extern "C++" { }; } } + +// PR5430 +namespace pr5430 { + extern "C" void func(void); +} +using namespace pr5430; +extern "C" void pr5430::func(void) { } |