diff options
| author | Douglas Gregor <dgregor@apple.com> | 2009-03-31 16:35:03 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2009-03-31 16:35:03 +0000 |
| commit | f1b876d5dee320019ef9819810ac5b76df5ec465 (patch) | |
| tree | 8911d26a55d933dcd10929ad1a53a2f7d4d5002c /clang/lib | |
| parent | 9277379fc03375cd000732ce4d1cf7408954ada7 (diff) | |
| download | bcm5719-llvm-f1b876d5dee320019ef9819810ac5b76df5ec465.tar.gz bcm5719-llvm-f1b876d5dee320019ef9819810ac5b76df5ec465.zip | |
Implement -Wmissing-prototypes. Fixes PR3911.
llvm-svn: 68110
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/Decl.cpp | 20 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 22 |
2 files changed, 42 insertions, 0 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 15a20bd050c..f0d32c75de6 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -341,6 +341,26 @@ bool FunctionDecl::isExternC(ASTContext &Context) const { return false; } +bool FunctionDecl::isGlobal() const { + if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(this)) + return Method->isStatic(); + + if (getStorageClass() == Static) + return false; + + for (const DeclContext *DC = getDeclContext(); + DC->isNamespace(); + DC = DC->getParent()) { + if (const NamespaceDecl *Namespace = cast<NamespaceDecl>(DC)) { + if (!Namespace->getDeclName()) + return false; + break; + } + } + + return true; +} + /// \brief Returns a value indicating whether this function /// corresponds to a builtin function. /// diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index be9a0e24d1f..584d2b11f9a 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2741,6 +2741,28 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) { diag::err_func_def_incomplete_result)) FD->setInvalidDecl(); + // GNU warning -Wmissing-prototypes: + // Warn if a global function is defined without a previous + // prototype declaration. This warning is issued even if the + // definition itself provides a prototype. The aim is to detect + // global functions that fail to be declared in header files. + if (!FD->isInvalidDecl() && FD->isGlobal() && !isa<CXXMethodDecl>(FD)) { + bool MissingPrototype = true; + for (const FunctionDecl *Prev = FD->getPreviousDeclaration(); + Prev; Prev = Prev->getPreviousDeclaration()) { + // Ignore any declarations that occur in function or method + // scope, because they aren't visible from the header. + if (Prev->getDeclContext()->isFunctionOrMethod()) + continue; + + MissingPrototype = !Prev->getType()->isFunctionProtoType(); + break; + } + + if (MissingPrototype) + Diag(FD->getLocation(), diag::warn_missing_prototype) << FD; + } + PushDeclContext(FnBodyScope, FD); // Check the validity of our function parameters |

