[llvm-branch-commits] [cfe-branch] r121567 - in /cfe/branches/Apple/whitney: include/clang/AST/Decl.h lib/AST/Decl.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriterDecl.cpp test/CodeGenCXX/inline-functions.cpp

Daniel Dunbar daniel at zuster.org
Fri Dec 10 13:38:28 PST 2010


Author: ddunbar
Date: Fri Dec 10 15:38:27 2010
New Revision: 121567

URL: http://llvm.org/viewvc/llvm-project?rev=121567&view=rev
Log:
Merge r121373:
--
Author: Douglas Gregor <dgregor at apple.com>
Date:   Thu Dec 9 16:59:22 2010 +0000

    When an "inline" declaration was followed by a definition not marked
    "inline", we weren't giving the definition weak linkage because the
    "inline" bit wasn't propagated. This was a longstanding FIXME that,
    somehow, hadn't triggered a bug in the wild. Fix this problem by
    tracking whether any declaration was marked "inline", and clean up the
    semantics of GNU's "extern inline" semantics calculation based on this
    change.

    Fixes <rdar://problem/8740363>.

Modified:
    cfe/branches/Apple/whitney/include/clang/AST/Decl.h
    cfe/branches/Apple/whitney/lib/AST/Decl.cpp
    cfe/branches/Apple/whitney/lib/Serialization/ASTReaderDecl.cpp
    cfe/branches/Apple/whitney/lib/Serialization/ASTWriterDecl.cpp
    cfe/branches/Apple/whitney/test/CodeGenCXX/inline-functions.cpp

Modified: cfe/branches/Apple/whitney/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/include/clang/AST/Decl.h?rev=121567&r1=121566&r2=121567&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/include/clang/AST/Decl.h (original)
+++ cfe/branches/Apple/whitney/include/clang/AST/Decl.h Fri Dec 10 15:38:27 2010
@@ -1180,6 +1180,7 @@
   unsigned SClass : 2;
   unsigned SClassAsWritten : 2;
   bool IsInline : 1;
+  bool IsInlineSpecified : 1;
   bool IsVirtualAsWritten : 1;
   bool IsPure : 1;
   bool HasInheritedPrototype : 1;
@@ -1258,11 +1259,12 @@
 protected:
   FunctionDecl(Kind DK, DeclContext *DC, const DeclarationNameInfo &NameInfo,
                QualType T, TypeSourceInfo *TInfo,
-               StorageClass S, StorageClass SCAsWritten, bool isInline)
+               StorageClass S, StorageClass SCAsWritten, bool isInlineSpecified)
     : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo),
       DeclContext(DK),
       ParamInfo(0), Body(),
-      SClass(S), SClassAsWritten(SCAsWritten), IsInline(isInline),
+      SClass(S), SClassAsWritten(SCAsWritten), 
+      IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified),
       IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false),
       HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false),
       HasImplicitReturnZero(false),
@@ -1287,11 +1289,11 @@
                               TypeSourceInfo *TInfo,
                               StorageClass S = SC_None,
                               StorageClass SCAsWritten = SC_None,
-                              bool isInline = false,
+                              bool isInlineSpecified = false,
                               bool hasWrittenPrototype = true) {
     DeclarationNameInfo NameInfo(N, L);
     return FunctionDecl::Create(C, DC, NameInfo, T, TInfo, S, SCAsWritten,
-                                isInline, hasWrittenPrototype);
+                                isInlineSpecified, hasWrittenPrototype);
   }
 
   static FunctionDecl *Create(ASTContext &C, DeclContext *DC,
@@ -1299,7 +1301,7 @@
                               QualType T, TypeSourceInfo *TInfo,
                               StorageClass S = SC_None,
                               StorageClass SCAsWritten = SC_None,
-                              bool isInline = false,
+                              bool isInlineSpecified = false,
                               bool hasWrittenPrototype = true);
 
   DeclarationNameInfo getNameInfo() const {
@@ -1493,10 +1495,13 @@
 
   /// \brief Determine whether the "inline" keyword was specified for this
   /// function.
-  bool isInlineSpecified() const { return IsInline; }
+  bool isInlineSpecified() const { return IsInlineSpecified; }
                        
   /// Set whether the "inline" keyword was specified for this function.
-  void setInlineSpecified(bool I) { IsInline = I; }
+  void setInlineSpecified(bool I) { 
+    IsInlineSpecified = I; 
+    IsInline = I;
+  }
 
   /// \brief Determine whether this function should be inlined, because it is
   /// either marked "inline" or is a member function of a C++ class that

Modified: cfe/branches/Apple/whitney/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/lib/AST/Decl.cpp?rev=121567&r1=121566&r2=121567&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/lib/AST/Decl.cpp (original)
+++ cfe/branches/Apple/whitney/lib/AST/Decl.cpp Fri Dec 10 15:38:27 2010
@@ -1251,6 +1251,9 @@
     assert((!PrevDecl || PrevFunTmpl) && "Function/function template mismatch");
     FunTmpl->setPreviousDeclaration(PrevFunTmpl);
   }
+  
+  if (PrevDecl->IsInline)
+    IsInline = true;
 }
 
 const FunctionDecl *FunctionDecl::getCanonicalDecl() const {
@@ -1349,14 +1352,7 @@
 }
 
 bool FunctionDecl::isInlined() const {
-  // FIXME: This is not enough. Consider:
-  //
-  // inline void f();
-  // void f() { }
-  //
-  // f is inlined, but does not have inline specified.
-  // To fix this we should add an 'inline' flag to FunctionDecl.
-  if (isInlineSpecified())
+  if (IsInline)
     return true;
   
   if (isa<CXXMethodDecl>(this)) {
@@ -1410,20 +1406,22 @@
   ASTContext &Context = getASTContext();
   
   if (!Context.getLangOptions().C99 || hasAttr<GNUInlineAttr>()) {
-    // GNU inline semantics. Based on a number of examples, we came up with the
-    // following heuristic: if the "inline" keyword is present on a
-    // declaration of the function but "extern" is not present on that
-    // declaration, then the symbol is externally visible. Otherwise, the GNU
-    // "extern inline" semantics applies and the symbol is not externally
-    // visible.
+    // If it's not the case that both 'inline' and 'extern' are
+    // specified on the definition, then this inline definition is
+    // externally visible.
+    if (!(isInlineSpecified() && getStorageClassAsWritten() == SC_Extern))
+      return true;
+    
+    // If any declaration is 'inline' but not 'extern', then this definition
+    // is externally visible.
     for (redecl_iterator Redecl = redecls_begin(), RedeclEnd = redecls_end();
          Redecl != RedeclEnd;
          ++Redecl) {
-      if (Redecl->isInlineSpecified() && Redecl->getStorageClass() != SC_Extern)
+      if (Redecl->isInlineSpecified() && 
+          Redecl->getStorageClassAsWritten() != SC_Extern)
         return true;
-    }
+    }    
     
-    // GNU "extern inline" semantics; no externally visible symbol.
     return false;
   }
   
@@ -1995,9 +1993,10 @@
                                    const DeclarationNameInfo &NameInfo,
                                    QualType T, TypeSourceInfo *TInfo,
                                    StorageClass S, StorageClass SCAsWritten,
-                                   bool isInline, bool hasWrittenPrototype) {
+                                   bool isInlineSpecified, 
+                                   bool hasWrittenPrototype) {
   FunctionDecl *New = new (C) FunctionDecl(Function, DC, NameInfo, T, TInfo,
-                                           S, SCAsWritten, isInline);
+                                           S, SCAsWritten, isInlineSpecified);
   New->HasWrittenPrototype = hasWrittenPrototype;
   return New;
 }

Modified: cfe/branches/Apple/whitney/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/lib/Serialization/ASTReaderDecl.cpp?rev=121567&r1=121566&r2=121567&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/branches/Apple/whitney/lib/Serialization/ASTReaderDecl.cpp Fri Dec 10 15:38:27 2010
@@ -384,7 +384,8 @@
 
   FD->setStorageClass((StorageClass)Record[Idx++]);
   FD->setStorageClassAsWritten((StorageClass)Record[Idx++]);
-  FD->setInlineSpecified(Record[Idx++]);
+  FD->IsInline = Record[Idx++];
+  FD->IsInlineSpecified = Record[Idx++];
   FD->setVirtualAsWritten(Record[Idx++]);
   FD->setPure(Record[Idx++]);
   FD->setHasInheritedPrototype(Record[Idx++]);

Modified: cfe/branches/Apple/whitney/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/lib/Serialization/ASTWriterDecl.cpp?rev=121567&r1=121566&r2=121567&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/branches/Apple/whitney/lib/Serialization/ASTWriterDecl.cpp Fri Dec 10 15:38:27 2010
@@ -301,6 +301,7 @@
 
   Record.push_back(D->getStorageClass()); // FIXME: stable encoding
   Record.push_back(D->getStorageClassAsWritten());
+  Record.push_back(D->IsInline);
   Record.push_back(D->isInlineSpecified());
   Record.push_back(D->isVirtualAsWritten());
   Record.push_back(D->isPure());

Modified: cfe/branches/Apple/whitney/test/CodeGenCXX/inline-functions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/test/CodeGenCXX/inline-functions.cpp?rev=121567&r1=121566&r2=121567&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/test/CodeGenCXX/inline-functions.cpp (original)
+++ cfe/branches/Apple/whitney/test/CodeGenCXX/inline-functions.cpp Fri Dec 10 15:38:27 2010
@@ -21,3 +21,11 @@
 
 // CHECK: define void @_Z1fv
 void f() { }
+
+// <rdar://problem/8740363>
+inline void f1(int);
+
+// CHECK: define linkonce_odr void @_Z2f1i
+void f1(int) { }
+
+void test_f1() { f1(17); }





More information about the llvm-branch-commits mailing list