Skip to content

Commit 8d56f6c

Browse files
Always register asm attribute first in a Decl.
Previously, clang's SemaDecl processed `asm` attributes after every other attribute in the Decl, unlike gcc and clang's own parser which requires `asm` attributes to be the first one in the declaration (see llvm#162556). Therefore, move the processing of `asm` attributes to be the first one in the attributes list. Signed-off-by: Giuliano Belinassi <[email protected]>
1 parent caacfff commit 8d56f6c

File tree

3 files changed

+64
-50
lines changed

3 files changed

+64
-50
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,17 @@ AST Dumping Potentially Breaking Changes
128128

129129
- Default arguments of template template parameters are pretty-printed now.
130130

131+
- Pretty-printing of ``asm`` attributes are now always the first attribute
132+
on the right side of the declaration. Before we had, e.g.:
133+
134+
``__attribute__(("visibility")) asm("string")``
135+
136+
Now we have:
137+
138+
``asm("string") __attribute__(("visibility"))``
139+
140+
Which is accepted by both clang and gcc parsers.
141+
131142
Clang Frontend Potentially Breaking Changes
132143
-------------------------------------------
133144
- Members of anonymous unions/structs are now injected as ``IndirectFieldDecl``

clang/lib/Sema/SemaDecl.cpp

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -8124,56 +8124,6 @@ NamedDecl *Sema::ActOnVariableDeclarator(
81248124
}
81258125
}
81268126

8127-
// Handle attributes prior to checking for duplicates in MergeVarDecl
8128-
ProcessDeclAttributes(S, NewVD, D);
8129-
8130-
if (getLangOpts().HLSL)
8131-
HLSL().ActOnVariableDeclarator(NewVD);
8132-
8133-
if (getLangOpts().OpenACC)
8134-
OpenACC().ActOnVariableDeclarator(NewVD);
8135-
8136-
// FIXME: This is probably the wrong location to be doing this and we should
8137-
// probably be doing this for more attributes (especially for function
8138-
// pointer attributes such as format, warn_unused_result, etc.). Ideally
8139-
// the code to copy attributes would be generated by TableGen.
8140-
if (R->isFunctionPointerType())
8141-
if (const auto *TT = R->getAs<TypedefType>())
8142-
copyAttrFromTypedefToDecl<AllocSizeAttr>(*this, NewVD, TT);
8143-
8144-
if (getLangOpts().CUDA || getLangOpts().isTargetDevice()) {
8145-
if (EmitTLSUnsupportedError &&
8146-
((getLangOpts().CUDA && DeclAttrsMatchCUDAMode(getLangOpts(), NewVD)) ||
8147-
(getLangOpts().OpenMPIsTargetDevice &&
8148-
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(NewVD))))
8149-
Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
8150-
diag::err_thread_unsupported);
8151-
8152-
if (EmitTLSUnsupportedError &&
8153-
(LangOpts.SYCLIsDevice ||
8154-
(LangOpts.OpenMP && LangOpts.OpenMPIsTargetDevice)))
8155-
targetDiag(D.getIdentifierLoc(), diag::err_thread_unsupported);
8156-
// CUDA B.2.5: "__shared__ and __constant__ variables have implied static
8157-
// storage [duration]."
8158-
if (SC == SC_None && S->getFnParent() != nullptr &&
8159-
(NewVD->hasAttr<CUDASharedAttr>() ||
8160-
NewVD->hasAttr<CUDAConstantAttr>())) {
8161-
NewVD->setStorageClass(SC_Static);
8162-
}
8163-
}
8164-
8165-
// Ensure that dllimport globals without explicit storage class are treated as
8166-
// extern. The storage class is set above using parsed attributes. Now we can
8167-
// check the VarDecl itself.
8168-
assert(!NewVD->hasAttr<DLLImportAttr>() ||
8169-
NewVD->getAttr<DLLImportAttr>()->isInherited() ||
8170-
NewVD->isStaticDataMember() || NewVD->getStorageClass() != SC_None);
8171-
8172-
// In auto-retain/release, infer strong retension for variables of
8173-
// retainable type.
8174-
if (getLangOpts().ObjCAutoRefCount && ObjC().inferObjCARCLifetime(NewVD))
8175-
NewVD->setInvalidDecl();
8176-
81778127
// Handle GNU asm-label extension (encoded as an attribute).
81788128
if (Expr *E = D.getAsmLabel()) {
81798129
// The parser guarantees this is a string.
@@ -8234,6 +8184,56 @@ NamedDecl *Sema::ActOnVariableDeclarator(
82348184
}
82358185
}
82368186

8187+
// Handle attributes prior to checking for duplicates in MergeVarDecl
8188+
ProcessDeclAttributes(S, NewVD, D);
8189+
8190+
if (getLangOpts().HLSL)
8191+
HLSL().ActOnVariableDeclarator(NewVD);
8192+
8193+
if (getLangOpts().OpenACC)
8194+
OpenACC().ActOnVariableDeclarator(NewVD);
8195+
8196+
// FIXME: This is probably the wrong location to be doing this and we should
8197+
// probably be doing this for more attributes (especially for function
8198+
// pointer attributes such as format, warn_unused_result, etc.). Ideally
8199+
// the code to copy attributes would be generated by TableGen.
8200+
if (R->isFunctionPointerType())
8201+
if (const auto *TT = R->getAs<TypedefType>())
8202+
copyAttrFromTypedefToDecl<AllocSizeAttr>(*this, NewVD, TT);
8203+
8204+
if (getLangOpts().CUDA || getLangOpts().isTargetDevice()) {
8205+
if (EmitTLSUnsupportedError &&
8206+
((getLangOpts().CUDA && DeclAttrsMatchCUDAMode(getLangOpts(), NewVD)) ||
8207+
(getLangOpts().OpenMPIsTargetDevice &&
8208+
OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(NewVD))))
8209+
Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(),
8210+
diag::err_thread_unsupported);
8211+
8212+
if (EmitTLSUnsupportedError &&
8213+
(LangOpts.SYCLIsDevice ||
8214+
(LangOpts.OpenMP && LangOpts.OpenMPIsTargetDevice)))
8215+
targetDiag(D.getIdentifierLoc(), diag::err_thread_unsupported);
8216+
// CUDA B.2.5: "__shared__ and __constant__ variables have implied static
8217+
// storage [duration]."
8218+
if (SC == SC_None && S->getFnParent() != nullptr &&
8219+
(NewVD->hasAttr<CUDASharedAttr>() ||
8220+
NewVD->hasAttr<CUDAConstantAttr>())) {
8221+
NewVD->setStorageClass(SC_Static);
8222+
}
8223+
}
8224+
8225+
// Ensure that dllimport globals without explicit storage class are treated as
8226+
// extern. The storage class is set above using parsed attributes. Now we can
8227+
// check the VarDecl itself.
8228+
assert(!NewVD->hasAttr<DLLImportAttr>() ||
8229+
NewVD->getAttr<DLLImportAttr>()->isInherited() ||
8230+
NewVD->isStaticDataMember() || NewVD->getStorageClass() != SC_None);
8231+
8232+
// In auto-retain/release, infer strong retension for variables of
8233+
// retainable type.
8234+
if (getLangOpts().ObjCAutoRefCount && ObjC().inferObjCARCLifetime(NewVD))
8235+
NewVD->setInvalidDecl();
8236+
82378237
// Find the shadowed declaration before filtering for scope.
82388238
NamedDecl *ShadowedDecl = D.getCXXScopeSpec().isEmpty()
82398239
? getShadowedDeclaration(NewVD, Previous)

clang/test/Sema/attr-print.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,6 @@ int * __sptr * __ptr32 ppsp32;
3535

3636
// CHECK: __attribute__((availability(macos, strict, introduced=10.6)));
3737
void f6(int) __attribute__((availability(macosx,strict,introduced=10.6)));
38+
39+
// CHECK: _libc_intl_domainname asm("__gi__libc_intl_domainname") __attribute__((visibility("hidden")));
40+
extern const char _libc_intl_domainname[]; extern typeof (_libc_intl_domainname) _libc_intl_domainname asm("__gi__libc_intl_domainname") __attribute__((visibility("hidden")));

0 commit comments

Comments
 (0)