eugenis created this revision. eugenis added a reviewer: rsmith. eugenis added subscribers: cfe-commits, EricWF, rnk. eugenis set the repository for this revision to rL LLVM.
The attrubite is applicable to functions and variables and changes the linkage of the subject to internal. Following the proposal in http://lists.llvm.org/pipermail/cfe-dev/2015-October/045580.html Repository: rL LLVM http://reviews.llvm.org/D13925 Files: include/clang/Basic/Attr.td include/clang/Basic/AttrDocs.td lib/AST/ASTContext.cpp lib/Sema/Sema.cpp lib/Sema/SemaDeclAttr.cpp test/CodeGenCXX/internal_linkage.cpp test/Sema/internal_linkage.c test/SemaCXX/internal_linkage.cpp
Index: test/SemaCXX/internal_linkage.cpp =================================================================== --- /dev/null +++ test/SemaCXX/internal_linkage.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +int f() __attribute__((internal_linkage)); +class __attribute__((internal_linkage)) A { // expected-warning{{'internal_linkage' attribute only applies to variables and functions}} +public: + int x __attribute__((internal_linkage)); // expected-warning{{'internal_linkage' attribute only applies to variables and functions}} + static int y __attribute__((internal_linkage)); + void f1() __attribute__((internal_linkage)); + void f2() __attribute__((internal_linkage)) {} + static void f3() __attribute__((internal_linkage)) {} + A() __attribute__((internal_linkage)) {} + ~A() __attribute__((internal_linkage)) {} +}; + +int A::y; + +void A::f1() { +} Index: test/Sema/internal_linkage.c =================================================================== --- /dev/null +++ test/Sema/internal_linkage.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +int var __attribute__((internal_linkage)); +int var2 __attribute__((internal_linkage,common)); // expected-warning{{'internal_linkage' attribute ignored}} \ + // expected-note{{conflicting attribute is here}} +int f() __attribute__((internal_linkage)); +struct __attribute__((internal_linkage)) S { // expected-warning{{'internal_linkage' attribute only applies to variables and functions}} +}; Index: test/CodeGenCXX/internal_linkage.cpp =================================================================== --- /dev/null +++ test/CodeGenCXX/internal_linkage.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s + +__attribute__((internal_linkage)) static void f() {} + +class A { +public: + static int y __attribute__((internal_linkage)); + void f1() __attribute__((internal_linkage)); + void f2() __attribute__((internal_linkage)) {} + void f3(); + static void f4() __attribute__((internal_linkage)) {} + A() __attribute__((internal_linkage)) {} + ~A() __attribute__((internal_linkage)) {} +}; + +int A::y; + +void A::f1() { +} + +void A::f3() __attribute__((internal_linkage)) { +} + +void use() { + A a; + a.f1(); + a.f2(); + a.f3(); + A::f4(); + f(); + int &Y = A::y; +} + +// CHECK-DAG: @_ZN1A1yE = internal global +// CHECK-DAG: define internal void @_ZL1fv +// CHECK-DAG: define internal void @_ZN1AC1Ev +// CHECK-DAG: define internal void @_ZN1AC2Ev +// CHECK-DAG: define internal void @_ZN1AD1Ev +// CHECK-DAG: define internal void @_ZN1AD2Ev +// CHECK-DAG: define internal void @_ZN1A2f1Ev +// CHECK-DAG: define internal void @_ZN1A2f2Ev +// CHECK-DAG: define internal void @_ZN1A2f3Ev +// CHECK-DAG: define internal void @_ZN1A2f4Ev Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -1573,7 +1573,14 @@ static void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) { if (S.LangOpts.CPlusPlus) { S.Diag(Attr.getLoc(), diag::err_attribute_not_supported_in_lang) - << Attr.getName() << AttributeLangSupport::Cpp; + << Attr.getName() << AttributeLangSupport::Cpp; + return; + } + + if (InternalLinkageAttr *Internal = D->getAttr<InternalLinkageAttr>()) { + S.Diag(Attr.getRange().getBegin(), diag::warn_attribute_ignored) + << Attr.getName(); + S.Diag(Internal->getLocation(), diag::note_conflicting_attribute); return; } @@ -4550,6 +4557,20 @@ Attr.getAttributeSpellingListIndex())); } +static void handleInternalLinkageAttr(Sema &S, Decl *D, + const AttributeList &Attr) { + if (CommonAttr *Common = D->getAttr<CommonAttr>()) { + S.Diag(Attr.getRange().getBegin(), diag::warn_attribute_ignored) + << Attr.getName(); + S.Diag(Common->getLocation(), diag::note_conflicting_attribute); + return; + } + + if (!D->hasAttr<InternalLinkageAttr>()) + D->addAttr(::new (S.Context) InternalLinkageAttr( + Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); +} + /// 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. @@ -4991,6 +5012,9 @@ case AttributeList::AT_OpenCLImageAccess: handleSimpleAttribute<OpenCLImageAccessAttr>(S, D, Attr); break; + case AttributeList::AT_InternalLinkage: + handleInternalLinkageAttr(S, D, Attr); + break; // Microsoft attributes: case AttributeList::AT_MSNoVTable: Index: lib/Sema/Sema.cpp =================================================================== --- lib/Sema/Sema.cpp +++ lib/Sema/Sema.cpp @@ -536,7 +536,7 @@ continue; } - if (!ND->isExternallyVisible()) { + if (!ND->isExternallyVisible() || ND->hasAttr<InternalLinkageAttr>()) { S.Diag(ND->getLocation(), diag::warn_undefined_internal) << isa<VarDecl>(ND) << ND; } else { Index: lib/AST/ASTContext.cpp =================================================================== --- lib/AST/ASTContext.cpp +++ lib/AST/ASTContext.cpp @@ -8304,6 +8304,8 @@ } else if (D->hasAttr<DLLExportAttr>() || D->hasAttr<CUDAGlobalAttr>()) { if (L == GVA_DiscardableODR) return GVA_StrongODR; + } else if (D->hasAttr<InternalLinkageAttr>()) { + return GVA_Internal; } return L; } Index: include/clang/Basic/AttrDocs.td =================================================================== --- include/clang/Basic/AttrDocs.td +++ include/clang/Basic/AttrDocs.td @@ -1612,3 +1612,10 @@ arguments, with arbitrary offsets. }]; } + +def InternalLinkageDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +The ``internal_linkage`` attribute changes the linkage type of the declaration to internal. + }]; +} Index: include/clang/Basic/Attr.td =================================================================== --- include/clang/Basic/Attr.td +++ include/clang/Basic/Attr.td @@ -2108,3 +2108,9 @@ let SemaHandler = 0; let Documentation = [Undocumented]; } + +def InternalLinkage : InheritableAttr { + let Spellings = [GCC<"internal_linkage">]; + let Subjects = SubjectList<[Function,Var]>; + let Documentation = [InternalLinkageDocs]; +}
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits