yaxunl updated the summary for this revision.
yaxunl removed rL LLVM as the repository for this revision.
yaxunl updated this revision to Diff 51297.
yaxunl added a comment.

Simplify description of this attribute in AttrDocs since it causes some 
confusion.


http://reviews.llvm.org/D18095

Files:
  include/clang/Basic/Attr.td
  include/clang/Basic/AttrDocs.td
  include/clang/Sema/Sema.h
  lib/CodeGen/CodeGenModule.cpp
  lib/Sema/SemaDeclAttr.cpp
  test/CodeGen/attr-linkonce-odr-linkage.c
  test/Sema/attr-linkonce-odr-linkage.c

Index: test/Sema/attr-linkonce-odr-linkage.c
===================================================================
--- /dev/null
+++ test/Sema/attr-linkonce-odr-linkage.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+
+extern int g0 __attribute__((linkonce_odr_linkage));
+int g2 __attribute__((linkonce_odr_linkage));
+int __attribute__((linkonce_odr_linkage)) g4(void);
+void __attribute__((linkonce_odr_linkage)) g5(void) {
+}
+
+struct __attribute__((linkonce_odr_linkage)) s0 {}; // expected-warning {{'linkonce_odr_linkage' attribute only applies to variables and functions}}
+
+static int x __attribute__((linkonce_odr_linkage)); // expected-error {{weak declaration cannot have internal linkage}}
+
+int C; // expected-note {{previous definition is here}}
+extern int C __attribute__((linkonce_odr_linkage)); // expected-warning {{an already-declared variable is made a weak_import declaration}}
+
+static int pr14946_x;
+extern int pr14946_x  __attribute__((linkonce_odr_linkage)); // expected-error {{weak declaration cannot have internal linkage}}
+
+static void pr14946_f();
+void pr14946_f() __attribute__((linkonce_odr_linkage)); // expected-error {{weak declaration cannot have internal linkage}}
Index: test/CodeGen/attr-linkonce-odr-linkage.c
===================================================================
--- /dev/null
+++ test/CodeGen/attr-linkonce-odr-linkage.c
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -emit-llvm -triple i386-linux-gnu < %s | FileCheck %s
+
+// CHECK: @a = linkonce_odr global i32 0
+__attribute__((linkonce_odr_linkage)) int a;
+
+// CHECK: define linkonce_odr void @test1_g()
+void test1_g(void) __attribute__((linkonce_odr_linkage));
+
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -3611,6 +3611,19 @@
       InternalLinkageAttr(Range, Context, AttrSpellingListIndex);
 }
 
+LinkOnceODRLinkageAttr *
+Sema::mergeLinkOnceODRLinkageAttr(Decl *D, SourceRange Range,
+                                  IdentifierInfo *Ident,
+                                  unsigned AttrSpellingListIndex) {
+  if (checkAttrMutualExclusion<InternalLinkageAttr>(*this, D, Range, Ident) ||
+      checkAttrMutualExclusion<CommonAttr>(*this, D, Range, Ident))
+    return nullptr;
+
+  return ::new (Context) LinkOnceODRLinkageAttr(Range,
+                                                Context,
+                                                AttrSpellingListIndex);
+}
+
 MinSizeAttr *Sema::mergeMinSizeAttr(Decl *D, SourceRange Range,
                                     unsigned AttrSpellingListIndex) {
   if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) {
@@ -5206,6 +5219,14 @@
     D->addAttr(Internal);
 }
 
+static void handleLinkOnceODRLinkageAttr(Sema &S, Decl *D,
+                                      const AttributeList &Attr) {
+  if (LinkOnceODRLinkageAttr *LinkOnce =
+          S.mergeLinkOnceODRLinkageAttr(D, Attr.getRange(), Attr.getName(),
+                                        Attr.getAttributeSpellingListIndex()))
+    D->addAttr(LinkOnce);
+}
+
 /// Handles semantic checking for features that are common to all attributes,
 /// such as checking whether a parameter was properly specified, or the correct
 /// number of arguments were passed, etc.
@@ -5701,6 +5722,8 @@
   case AttributeList::AT_InternalLinkage:
     handleInternalLinkageAttr(S, D, Attr);
     break;
+  case AttributeList::AT_LinkOnceODRLinkage:
+    handleLinkOnceODRLinkageAttr(S, D, Attr);
 
   // Microsoft attributes:
   case AttributeList::AT_MSNoVTable:
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -752,7 +752,6 @@
 llvm::GlobalValue::LinkageTypes
 CodeGenModule::getFunctionLinkage(GlobalDecl GD) {
   const auto *D = cast<FunctionDecl>(GD.getDecl());
-
   GVALinkage Linkage = getContext().GetGVALinkageForFunction(D);
 
   if (isa<CXXDestructorDecl>(D) &&
@@ -2626,6 +2625,9 @@
 
 llvm::GlobalValue::LinkageTypes CodeGenModule::getLLVMLinkageForDeclarator(
     const DeclaratorDecl *D, GVALinkage Linkage, bool IsConstantVariable) {
+  if (D->hasAttr<LinkOnceODRLinkageAttr>())
+    return llvm::GlobalVariable::LinkOnceODRLinkage;
+
   if (Linkage == GVA_Internal)
     return llvm::Function::InternalLinkage;
 
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -2144,6 +2144,10 @@
                                                 unsigned AttrSpellingListIndex);
   CommonAttr *mergeCommonAttr(Decl *D, SourceRange Range, IdentifierInfo *Ident,
                               unsigned AttrSpellingListIndex);
+  LinkOnceODRLinkageAttr *
+  mergeLinkOnceODRLinkageAttr(Decl *D, SourceRange Range,
+                              IdentifierInfo *Ident,
+                              unsigned AttrSpellingListIndex);
 
   void mergeDeclAttributes(NamedDecl *New, Decl *Old,
                            AvailabilityMergeKind AMK = AMK_Redeclaration);
Index: include/clang/Basic/AttrDocs.td
===================================================================
--- include/clang/Basic/AttrDocs.td
+++ include/clang/Basic/AttrDocs.td
@@ -1924,6 +1924,13 @@
   }];
 }
 
+def LinkOnceODRLinkageDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+The ``linkonce_odr_linkage`` attribute changes the linkage type of the declaration to linkonce_odr.
+  }];
+}
+
 def DisableTailCallsDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{
Index: include/clang/Basic/Attr.td
===================================================================
--- include/clang/Basic/Attr.td
+++ include/clang/Basic/Attr.td
@@ -2249,3 +2249,9 @@
   let Subjects = SubjectList<[Var, Function, CXXRecord]>;
   let Documentation = [InternalLinkageDocs];
 }
+
+def LinkOnceODRLinkage : InheritableAttr {
+  let Spellings = [GNU<"linkonce_odr_linkage">];
+  let Subjects = SubjectList<[Var, Function]>;
+  let Documentation = [LinkOnceODRLinkageDocs];
+}
\ No newline at end of file
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to