diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-09-12 18:37:38 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-09-12 18:37:38 +0000 |
commit | e389585f8a40f80004d3b98b99f3980305ef78a0 (patch) | |
tree | dc6db711766f25c9365a0d2fa9b1376e937594bc /lib/Sema/SemaDecl.cpp | |
parent | 773d847fbe93479f7499e2076c9d8d99870c5fb0 (diff) |
Diagnose attempt to mark function-local declarations as __module_private__.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139519 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 42 |
1 files changed, 35 insertions, 7 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 432354cc7d..b33294d7c3 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -2373,6 +2373,12 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, if (DS.isExplicitSpecified()) Diag(DS.getExplicitSpecLoc(), diag::warn_standalone_specifier) <<"explicit"; + if (DS.isModulePrivateSpecified() && + Tag && Tag->getDeclContext()->isFunctionOrMethod()) + Diag(DS.getModulePrivateSpecLoc(), diag::err_module_private_local_class) + << Tag->getTagKind() + << FixItHint::CreateRemoval(DS.getModulePrivateSpecLoc()); + // FIXME: Warn on useless attributes return TagD; @@ -3818,6 +3824,10 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, } } + // Set the lexical context. If the declarator has a C++ scope specifier, the + // lexical context will be different from the semantic context. + NewVD->setLexicalDeclContext(CurContext); + if (D.getDeclSpec().isThreadSpecified()) { if (NewVD->hasLocalStorage()) Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_thread_non_global); @@ -3832,14 +3842,15 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, Diag(NewVD->getLocation(), diag::err_module_private_specialization) << 2 << FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc()); + else if (NewVD->hasLocalStorage()) + Diag(NewVD->getLocation(), diag::err_module_private_local) + << 0 << NewVD->getDeclName() + << SourceRange(D.getDeclSpec().getModulePrivateSpecLoc()) + << FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc()); else NewVD->setModulePrivate(); } - // Set the lexical context. If the declarator has a C++ scope specifier, the - // lexical context will be different from the semantic context. - NewVD->setLexicalDeclContext(CurContext); - // Handle attributes prior to checking for duplicates in MergeVarDecl ProcessDeclAttributes(S, NewVD, D); @@ -6357,6 +6368,12 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { ProcessDeclAttributes(S, New, D); + if (D.getDeclSpec().isModulePrivateSpecified()) + Diag(New->getLocation(), diag::err_module_private_local) + << 1 << New->getDeclName() + << SourceRange(D.getDeclSpec().getModulePrivateSpecLoc()) + << FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc()); + if (New->hasAttr<BlocksAttr>()) { Diag(New->getLocation(), diag::err_block_on_nonlocal); } @@ -7021,8 +7038,15 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T, return NewTD; } - if (D.getDeclSpec().isModulePrivateSpecified()) - NewTD->setModulePrivate(); + if (D.getDeclSpec().isModulePrivateSpecified()) { + if (CurContext->isFunctionOrMethod()) + Diag(NewTD->getLocation(), diag::err_module_private_local) + << 2 << NewTD->getDeclName() + << SourceRange(D.getDeclSpec().getModulePrivateSpecLoc()) + << FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc()); + else + NewTD->setModulePrivate(); + } // C++ [dcl.typedef]p8: // If the typedef declaration defines an unnamed class (or @@ -7777,7 +7801,11 @@ CreateNewDecl: << FixItHint::CreateRemoval(ModulePrivateLoc); else if (PrevDecl && !PrevDecl->isModulePrivate()) diagnoseModulePrivateRedeclaration(New, PrevDecl, ModulePrivateLoc); - else + // __module_private__ does not apply to local classes. However, we only + // diagnose this as an error when the declaration specifiers are + // freestanding. Here, we just ignore the __module_private__. + // foobar + else if (!SearchDC->isFunctionOrMethod()) New->setModulePrivate(); } |