summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-03-31 16:35:03 +0000
committerDouglas Gregor <dgregor@apple.com>2009-03-31 16:35:03 +0000
commitf1b876d5dee320019ef9819810ac5b76df5ec465 (patch)
tree8911d26a55d933dcd10929ad1a53a2f7d4d5002c /clang/lib
parent9277379fc03375cd000732ce4d1cf7408954ada7 (diff)
downloadbcm5719-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.cpp20
-rw-r--r--clang/lib/Sema/SemaDecl.cpp22
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
OpenPOWER on IntegriCloud