Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions clang/examples/Attribute/Attribute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ struct ExampleAttrInfo : public ParsedAttrInfo {
bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr,
const Decl *D) const override {
// This attribute appertains to functions only.
if (!isa<FunctionDecl>(D)) {
if (!isa<FunctionDecl>(D) && !isa<LabelDecl>(D)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type_str)
<< Attr << Attr.isRegularKeywordAttribute() << "functions";
<< Attr << Attr.isRegularKeywordAttribute() << "functions or labels";
return false;
}
return true;
Expand All @@ -52,7 +52,7 @@ struct ExampleAttrInfo : public ParsedAttrInfo {
AttrHandling handleDeclAttribute(Sema &S, Decl *D,
const ParsedAttr &Attr) const override {
// Check if the decl is at file scope.
if (!D->getDeclContext()->isFileContext()) {
if (!D->getDeclContext()->isFileContext() && !isa<LabelDecl>(D)) {
unsigned ID = S.getDiagnostics().getCustomDiagID(
DiagnosticsEngine::Error,
"'example' attribute only allowed at file scope");
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/AST/ASTNodeTraverser.h
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,11 @@ class ASTNodeTraverser
Visit(A);
}

void VisitLabelStmt(const LabelStmt *Node) {
for (const auto *A : Node->getDecl()->getAttrs())
Visit(A);
}

void VisitCXXCatchStmt(const CXXCatchStmt *Node) {
Visit(Node->getExceptionDecl());
}
Expand Down
16 changes: 13 additions & 3 deletions clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -990,6 +990,7 @@ Decl *
TemplateDeclInstantiator::VisitLabelDecl(LabelDecl *D) {
LabelDecl *Inst = LabelDecl::Create(SemaRef.Context, Owner, D->getLocation(),
D->getIdentifier());
SemaRef.InstantiateAttrs(TemplateArgs, D, Inst, LateAttrs, StartingScope);
Owner->addDecl(Inst);
return Inst;
}
Expand All @@ -1009,6 +1010,7 @@ TemplateDeclInstantiator::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
D->getQualifierLoc(),
D->getTargetNameLoc(),
D->getNamespace());
SemaRef.InstantiateAttrs(TemplateArgs, D, Inst, LateAttrs, StartingScope);
Owner->addDecl(Inst);
return Inst;
}
Expand Down Expand Up @@ -1095,15 +1097,21 @@ Decl *TemplateDeclInstantiator::InstantiateTypedefNameDecl(TypedefNameDecl *D,

Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {
Decl *Typedef = InstantiateTypedefNameDecl(D, /*IsTypeAlias=*/false);
if (Typedef)
if (Typedef) {
SemaRef.InstantiateAttrs(TemplateArgs, D, Typedef, LateAttrs,
StartingScope);
Owner->addDecl(Typedef);
}
return Typedef;
}

Decl *TemplateDeclInstantiator::VisitTypeAliasDecl(TypeAliasDecl *D) {
Decl *Typedef = InstantiateTypedefNameDecl(D, /*IsTypeAlias=*/true);
if (Typedef)
if (Typedef) {
SemaRef.InstantiateAttrs(TemplateArgs, D, Typedef, LateAttrs,
StartingScope);
Owner->addDecl(Typedef);
}
return Typedef;
}

Expand Down Expand Up @@ -1160,8 +1168,10 @@ Decl *TemplateDeclInstantiator::InstantiateTypeAliasTemplateDecl(
Decl *
TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
Decl *Inst = InstantiateTypeAliasTemplateDecl(D);
if (Inst)
if (Inst) {
SemaRef.InstantiateAttrs(TemplateArgs, D, Inst, LateAttrs, StartingScope);
Owner->addDecl(Inst);
}

return Inst;
}
Expand Down
8 changes: 8 additions & 0 deletions clang/test/Frontend/plugin-attribute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ void fn2() __attribute__((example("somestring", 1, 2.0))) {
}
template <int N> void template_fn() __attribute__((example("template", N))) {
__attribute__((example("def", N + 1))) for (int i = 0; i < 9; ++i) {}
__attribute__((example("ghi", N + 2)))
label1:
for (int i = 0; i < 9; ++i) {}
}
void fn3() { template_fn<5>(); }
// CHECK: -AttributedStmt 0x{{[0-9a-z]+}} {{<line:[0-9]+:[0-9]+(, col:[0-9]+)?>}}
Expand All @@ -44,6 +47,11 @@ void fn3() { template_fn<5>(); }
// CHECK: -IntegerLiteral 0x{{[0-9a-z]+}} {{<line:[0-9]+:[0-9]+(, col:[0-9]+)?>}} 'int' 5
// CHECK: -IntegerLiteral 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} 'int' 1
// CHECK: -AnnotateAttr 0x{{[0-9a-z]+}} {{<line:[0-9]+:[0-9]+(, col:[0-9]+)?>}} "example"
// CHECK: -StringLiteral 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} 'const char[{{[0-9]+}}]' lvalue "ghi"
// CHECK: -BinaryOperator 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} 'int' '+'
// CHECK: -IntegerLiteral 0x{{[0-9a-z]+}} {{<line:[0-9]+:[0-9]+(, col:[0-9]+)?>}} 'int' 5
// CHECK: -IntegerLiteral 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} 'int' 2
// CHECK: -AnnotateAttr 0x{{[0-9a-z]+}} {{<line:[0-9]+:[0-9]+(, col:[0-9]+)?>}} "example"
// CHECK: -StringLiteral 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} 'const char[{{[0-9]+}}]' lvalue "template"
// CHECK: -IntegerLiteral 0x{{[0-9a-z]+}} {{<col:[0-9]+(, col:[0-9]+)?>}} 'int' 5

Expand Down
4 changes: 2 additions & 2 deletions clang/test/SemaCXX/attr-mode-tmpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ void CheckEnumerations() {
// Check that non-vector 'mode' attribute is OK with enumeration types.
typedef T __attribute__((mode(QI))) T1;
typedef T T2 __attribute__((mode(HI)));
typedef T __attribute__((mode(V8SI))) T3; // expected-error{{mode 'V8SI' is not supported for enumeration types}}
typedef T __attribute__((mode(V8SI))) T3; // expected-error2{{mode 'V8SI' is not supported for enumeration types}}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it should just cause the expected check to go away? What is going on here? If this is causing it to happen 2x, we might wonder if the attribute mode should have not been generated if it errored the 1st time.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, unfortunately the way InstantiateAttrs is implemented seems to cause it to copy attributes even if they errored previously. You can see this used elsewhere in the same file for much the same reason... this is a case where we're just having a pre-existing problem show up in a new scenario.

// expected-warning@-1{{specifying vector types with the 'mode' attribute is deprecated}}

typedef enum __attribute__((mode(HI))) { A4, B4 } T4;
Expand Down Expand Up @@ -62,7 +62,7 @@ struct TemplatedStruct {

// Check typedefs.
typedef T __attribute__((mode(DI))) T1;
typedef T __attribute__((mode(V8DI))) T2; // expected-error{{mode 'V8DI' is not supported for enumeration types}}
typedef T __attribute__((mode(V8DI))) T2; // expected-error2{{mode 'V8DI' is not supported for enumeration types}}
// expected-warning@-1{{deprecated}}

// Check parameters.
Expand Down
Loading