diff options
author | Chris Lattner <sabre@nondot.org> | 2009-04-14 06:44:48 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-04-14 06:44:48 +0000 |
commit | dbb5a376c8b9272813a30c5519031e9ea2fb071f (patch) | |
tree | 91bc12076b85ed1569d71d20ac4d49941dcb28bd | |
parent | d5ee6677c5f22409039a019accf41ec3937afe99 (diff) |
defer emission of always_inline, extern_inline, and inline functions (when
not in c89 mode).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69032 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 27 | ||||
-rw-r--r-- | test/CodeGen/function-attributes.c | 3 | ||||
-rw-r--r-- | test/CodeGen/inline.c | 10 |
3 files changed, 24 insertions, 16 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 5ef57ffdcc..c771461704 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -482,18 +482,23 @@ bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) { if (FD->hasAttr<ConstructorAttr>() || FD->hasAttr<DestructorAttr>()) return false; - // FIXME: What about inline, and/or extern inline? - if (FD->getStorageClass() != FunctionDecl::Static) - return false; - } else { - const VarDecl *VD = cast<VarDecl>(Global); - assert(VD->isFileVarDecl() && "Invalid decl"); - - if (VD->getStorageClass() != VarDecl::Static) - return false; + GVALinkage Linkage = GetLinkageForFunctionOrMethodDecl(FD); + + // static, static inline, always_inline, and extern inline functions can + // always be deferred. + if (Linkage == GVA_Internal || Linkage == GVA_ExternInline) + return true; + + // inline functions can be deferred unless we're in C89 mode. + if (Linkage == GVA_Inline && (Features.C99 || Features.CPlusPlus)) + return true; + + return false; } - - return true; + + const VarDecl *VD = cast<VarDecl>(Global); + assert(VD->isFileVarDecl() && "Invalid decl"); + return VD->getStorageClass() == VarDecl::Static; } void CodeGenModule::EmitGlobal(const ValueDecl *Global) { diff --git a/test/CodeGen/function-attributes.c b/test/CodeGen/function-attributes.c index a12111ec94..3269f98a56 100644 --- a/test/CodeGen/function-attributes.c +++ b/test/CodeGen/function-attributes.c @@ -7,7 +7,6 @@ // RUN: grep 'define zeroext i16 @f5(i32 %x) nounwind' %t && // RUN: grep 'define void @f6(i16 signext %x) nounwind' %t && // RUN: grep 'define void @f7(i16 zeroext %x) nounwind' %t && -// RUN: grep 'define void @f8() nounwind alwaysinline' %t && signed char f0(int x) { return x; } @@ -25,6 +24,8 @@ void f6(signed short x) { } void f7(unsigned short x) { } +// F8 is dead so it should not be emitted. +// RUN: not grep '@f8' %t && void __attribute__((always_inline)) f8(void) { } // RUN: grep 'call void @f9_t() noreturn' %t && diff --git a/test/CodeGen/inline.c b/test/CodeGen/inline.c index 8360896f36..fa2794780b 100644 --- a/test/CodeGen/inline.c +++ b/test/CodeGen/inline.c @@ -2,19 +2,20 @@ // RUN: grep "define available_externally i32 @ei()" %t && // RUN: grep "define i32 @foo()" %t && // RUN: grep "define i32 @bar()" %t && -// RUN: grep "define void @unreferenced()" %t && +// RUN: grep "define void @unreferenced1()" %t && +// RUN: not grep unreferenced2 %t && // RUN: clang %s -emit-llvm -S -o %t -std=c99 && // RUN: grep "define available_externally i32 @ei()" %t && // RUN: grep "define available_externally i32 @foo()" %t && // RUN: grep "define i32 @bar()" %t && -// RUN: grep "define available_externally void @unreferenced()" %t && +// RUN: not grep unreferenced %t && // RUN: clang %s -emit-llvm -S -o %t -std=c++98 && // RUN: grep "define available_externally i32 @_Z2eiv()" %t && // RUN: grep "define linkonce_odr i32 @_Z3foov()" %t && // RUN: grep "define i32 @_Z3barv()" %t && -// RUN: grep "define linkonce_odr void @_Z12unreferencedv()" %t +// RUN: not grep unreferenced %t extern inline int ei() { return 123; } @@ -25,5 +26,6 @@ inline int foo() { int bar() { return foo(); } -inline void unreferenced() {} +inline void unreferenced1() {} +extern inline void unreferenced2() {} |