[clang] 4a7aa25 - [X86][AsmParser] re-introduce 'offset' operator
Author: Eric Astor Date: 2019-12-30T14:35:26-05:00 New Revision: 4a7aa252a32a94b1bb61b3dc7f027b4a27ae334f URL: https://github.com/llvm/llvm-project/commit/4a7aa252a32a94b1bb61b3dc7f027b4a27ae334f DIFF: https://github.com/llvm/llvm-project/commit/4a7aa252a32a94b1bb61b3dc7f027b4a27ae334f.diff LOG: [X86][AsmParser] re-introduce 'offset' operator Summary: Amend MS offset operator implementation, to more closely fit with its MS counterpart: 1. InlineAsm: evaluate non-local source entities to their (address) location 2. Provide a mean with which one may acquire the address of an assembly label via MS syntax, rather than yielding a memory reference (i.e. "offset asm_label" and "$asm_label" should be synonymous 3. address PR32530 Based on http://llvm.org/D37461 Fix broken test where the break appears unrelated. - Set up appropriate memory-input rewrites for variable references. - Intel-dialect assembly printing now correctly handles addresses by adding "offset". - Pass offsets as immediate operands (using "r" constraint for offsets of locals). Reviewed By: rnk Differential Revision: https://reviews.llvm.org/D71436 Added: llvm/test/CodeGen/X86/offset-operator.ll llvm/test/MC/X86/pr32530.s Modified: clang/lib/Sema/SemaStmtAsm.cpp clang/test/CodeGen/ms-inline-asm-64.c clang/test/CodeGen/ms-inline-asm.c clang/test/CodeGen/ms-inline-asm.cpp clang/test/Parser/ms-inline-asm.c llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h llvm/lib/MC/MCParser/AsmParser.cpp llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp llvm/lib/Target/X86/AsmParser/X86Operand.h llvm/lib/Target/X86/X86AsmPrinter.cpp llvm/test/CodeGen/X86/ms-inline-asm.ll Removed: diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp index 5161b8001918..93faf2d151f9 100644 --- a/clang/lib/Sema/SemaStmtAsm.cpp +++ b/clang/lib/Sema/SemaStmtAsm.cpp @@ -707,8 +707,13 @@ void Sema::FillInlineAsmIdentifierInfo(Expr *Res, if (T->isFunctionType() || T->isDependentType()) return Info.setLabel(Res); if (Res->isRValue()) { -if (isa(T) && Res->EvaluateAsRValue(Eval, Context)) +bool IsEnum = isa(T); +if (DeclRefExpr *DRE = dyn_cast(Res)) + if (DRE->getDecl()->getKind() == Decl::EnumConstant) +IsEnum = true; +if (IsEnum && Res->EvaluateAsRValue(Eval, Context)) return Info.setEnum(Eval.Val.getInt().getSExtValue()); + return Info.setLabel(Res); } unsigned Size = Context.getTypeSizeInChars(T).getQuantity(); diff --git a/clang/test/CodeGen/ms-inline-asm-64.c b/clang/test/CodeGen/ms-inline-asm-64.c index 5b144eb7bb68..ce46b8821dee 100644 --- a/clang/test/CodeGen/ms-inline-asm-64.c +++ b/clang/test/CodeGen/ms-inline-asm-64.c @@ -12,10 +12,10 @@ void t1() { void t2() { int var = 10; - __asm mov [eax], offset var + __asm mov qword ptr [eax], offset var // CHECK: t2 // CHECK: call void asm sideeffect inteldialect -// CHECK-SAME: mov [eax], $0 +// CHECK-SAME: mov qword ptr [eax], $0 // CHECK-SAME: "r,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) } diff --git a/clang/test/CodeGen/ms-inline-asm.c b/clang/test/CodeGen/ms-inline-asm.c index 0c9b35a64523..17526f522311 100644 --- a/clang/test/CodeGen/ms-inline-asm.c +++ b/clang/test/CodeGen/ms-inline-asm.c @@ -190,14 +190,20 @@ void t15() { // CHECK: mov eax, $1 __asm mov eax, offset gvar ; eax = address of gvar // CHECK: mov eax, $2 -// CHECK: "*m,r,r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* @{{.*}}) + __asm mov eax, offset gvar+1 ; eax = 1 + address of gvar +// CHECK: mov eax, $3 + $$1 + __asm mov eax, 1+offset gvar ; eax = 1 + address of gvar +// CHECK: mov eax, $4 + $$1 + __asm mov eax, 1+offset gvar+1 ; eax = 2 + address of gvar +// CHECK: mov eax, $5 + $$2 +// CHECK: "*m,r,i,i,i,i,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* @{{.*}}, i32* @{{.*}}, i32* @{{.*}}, i32* @{{.*}}) } void t16() { int var = 10; - __asm mov [eax], offset var + __asm mov dword ptr [eax], offset var // CHECK: t16 -// CHECK: call void asm sideeffect inteldialect "mov [eax], $0", "r,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) +// CHECK: call void asm sideeffect inteldialect "mov dword ptr [eax], $0", "r,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}) } void t17() { diff --git a/clang/test/CodeGen/ms-inline-asm.cpp b/clang/test/CodeGen/ms-inline-asm.cpp index 58796ed6378d..463ff0f6e349 100644 --- a/clang/test/CodeGen/ms-inline-asm.cpp +++ b/clang/test/CodeGen/ms-inline-asm.cpp @@ -40,7 +40,7 @@ void t2() { // CHECK: call void asm sideeffect inteldialect // CHECK-SAME: mov eax, $0 // CHECK-SAME: mov eax, $1 -// CHECK-SAME: "r,r,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_ZN3Foo3ptrE, i32** @_ZN3Foo3Bar3ptrE) +// CHECK-SAME: "i,i,~{eax},~{dirflag},~{fpsr},~{flags}"(i32** @_
[clang] 1c545f6 - [ms] [X86] Use "P" modifier on all branch-target operands in inline X86 assembly.
Author: Eric Astor Date: 2020-01-09T14:55:03-05:00 New Revision: 1c545f6dbcbb3ada2dfef2c6afbc1ca8939135cb URL: https://github.com/llvm/llvm-project/commit/1c545f6dbcbb3ada2dfef2c6afbc1ca8939135cb DIFF: https://github.com/llvm/llvm-project/commit/1c545f6dbcbb3ada2dfef2c6afbc1ca8939135cb.diff LOG: [ms] [X86] Use "P" modifier on all branch-target operands in inline X86 assembly. Summary: Extend D71677 to apply to all branch-target operands, rather than special-casing call instructions. Also add a regression test for llvm.org/PR44272, since this finishes fixing it. Reviewers: thakis, rnk Reviewed By: thakis Subscribers: merge_guards_bot, hiraditya, cfe-commits, llvm-commits Tags: #clang, #llvm Differential Revision: https://reviews.llvm.org/D72417 Added: Modified: clang/test/CodeGen/ms-inline-asm-64.c llvm/include/llvm/MC/MCInstrDesc.h llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h llvm/lib/MC/MCParser/AsmParser.cpp llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp llvm/lib/Target/X86/AsmParser/X86Operand.h llvm/lib/Target/X86/X86InstrControl.td llvm/lib/Target/X86/X86InstrInfo.td llvm/utils/TableGen/InstrInfoEmitter.cpp llvm/utils/TableGen/X86RecognizableInstr.cpp Removed: diff --git a/clang/test/CodeGen/ms-inline-asm-64.c b/clang/test/CodeGen/ms-inline-asm-64.c index ce46b8821dee..20e8228a04b6 100644 --- a/clang/test/CodeGen/ms-inline-asm-64.c +++ b/clang/test/CodeGen/ms-inline-asm-64.c @@ -58,3 +58,17 @@ int t4() { // CHECK-SAME: mov [ebx + $$4], ecx // CHECK-SAME: "*m,~{eax},~{ebx},~{dirflag},~{fpsr},~{flags}"(%struct.t3_type* %{{.*}}) } + +void bar() {} + +void t5() { + __asm { +call bar +jmp bar + } + // CHECK: t5 + // CHECK: call void asm sideeffect inteldialect + // CHECK-SAME: call qword ptr ${0:P} + // CHECK-SAME: jmp qword ptr ${1:P} + // CHECK-SAME: "*m,*m,~{dirflag},~{fpsr},~{flags}"(void (...)* bitcast (void ()* @bar to void (...)*), void (...)* bitcast (void ()* @bar to void (...)*)) +} diff --git a/llvm/include/llvm/MC/MCInstrDesc.h b/llvm/include/llvm/MC/MCInstrDesc.h index 8791ba3ba425..e6af40868c30 100644 --- a/llvm/include/llvm/MC/MCInstrDesc.h +++ b/llvm/include/llvm/MC/MCInstrDesc.h @@ -37,7 +37,12 @@ enum OperandConstraint { /// These are flags set on operands, but should be considered /// private, all access should go through the MCOperandInfo accessors. /// See the accessors for a description of what these are. -enum OperandFlags { LookupPtrRegClass = 0, Predicate, OptionalDef }; +enum OperandFlags { + LookupPtrRegClass = 0, + Predicate, + OptionalDef, + BranchTarget +}; /// Operands are tagged with one of the values of this enum. enum OperandType { @@ -98,6 +103,9 @@ class MCOperandInfo { /// Set if this operand is a optional def. bool isOptionalDef() const { return Flags & (1 << MCOI::OptionalDef); } + /// Set if this operand is a branch target. + bool isBranchTarget() const { return Flags & (1 << MCOI::BranchTarget); } + bool isGenericType() const { return OperandType >= MCOI::OPERAND_FIRST_GENERIC && OperandType <= MCOI::OPERAND_LAST_GENERIC; diff --git a/llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h b/llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h index 3dde0b8474a2..abb95628c2a9 100644 --- a/llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h +++ b/llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h @@ -71,10 +71,6 @@ class MCParsedAsmOperand { /// variable/label? Only valid when parsing MS-style inline assembly. virtual bool needAddressOf() const { return false; } - /// isCallOperand - Is this an operand of an inline-assembly call instruction? - /// Only valid when parsing MS-style inline assembly. - virtual bool isCallOperand() const { return false; } - /// isOffsetOfLocal - Do we need to emit code to get the offset of the local /// variable, rather than its value? Only valid when parsing MS-style inline /// assembly. diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index dc8132b627a6..94a44c1f93b1 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -5845,7 +5845,7 @@ bool AsmParser::parseMSInlineAsm( InputDecls.push_back(OpDecl); InputDeclsAddressOf.push_back(Operand.needAddressOf()); InputConstraints.push_back(Constraint.str()); -if (Operand.isCallOperand()) +if (Desc.OpInfo[i - 1].isBranchTarget()) AsmStrRewrites.emplace_back(AOK_CallInput, Start, SymName.size()); else AsmStrRewrites.emplace_back(AOK_Input, Start, SymName.size()); diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index 27c6a5f91428..69299ae9b00d 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86Asm
[clang] 85b641c - [ms] Rename ParsingInlineAsm functions/variables to reflect MS-specificity.
Author: Eric Astor Date: 2020-02-26T15:19:40-05:00 New Revision: 85b641c27aecee637d3f7ab25915f47438f55848 URL: https://github.com/llvm/llvm-project/commit/85b641c27aecee637d3f7ab25915f47438f55848 DIFF: https://github.com/llvm/llvm-project/commit/85b641c27aecee637d3f7ab25915f47438f55848.diff LOG: [ms] Rename ParsingInlineAsm functions/variables to reflect MS-specificity. Summary: ParsingInlineAsm was a misleading name. These values are only set for MS-style inline assembly. Reviewed By: rnk Tags: #clang, #llvm Differential Revision: https://reviews.llvm.org/D75198 Added: Modified: clang/lib/Parse/ParseStmtAsm.cpp llvm/include/llvm/MC/MCParser/MCAsmParser.h llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h llvm/lib/MC/MCParser/AsmParser.cpp llvm/lib/MC/MCParser/MasmParser.cpp llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp Removed: diff --git a/clang/lib/Parse/ParseStmtAsm.cpp b/clang/lib/Parse/ParseStmtAsm.cpp index b596aded867d..bf02dd6c02d4 100644 --- a/clang/lib/Parse/ParseStmtAsm.cpp +++ b/clang/lib/Parse/ParseStmtAsm.cpp @@ -631,8 +631,8 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) { // Change to the Intel dialect. Parser->setAssemblerDialect(1); Parser->setTargetParser(*TargetParser.get()); - Parser->setParsingInlineAsm(true); - TargetParser->setParsingInlineAsm(true); + Parser->setParsingMSInlineAsm(true); + TargetParser->setParsingMSInlineAsm(true); ClangAsmParserCallback Callback(*this, AsmLoc, AsmString, AsmToks, TokOffsets); diff --git a/llvm/include/llvm/MC/MCParser/MCAsmParser.h b/llvm/include/llvm/MC/MCParser/MCAsmParser.h index 9d9091306c13..7d57dd605fcb 100644 --- a/llvm/include/llvm/MC/MCParser/MCAsmParser.h +++ b/llvm/include/llvm/MC/MCParser/MCAsmParser.h @@ -165,8 +165,8 @@ class MCAsmParser { /// Run the parser on the input source buffer. virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false) = 0; - virtual void setParsingInlineAsm(bool V) = 0; - virtual bool isParsingInlineAsm() = 0; + virtual void setParsingMSInlineAsm(bool V) = 0; + virtual bool isParsingMSInlineAsm() = 0; /// Parse MS-style inline assembly. virtual bool parseMSInlineAsm( diff --git a/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h b/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h index 9ce1890916e9..ad086eaa539c 100644 --- a/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h +++ b/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h @@ -329,8 +329,8 @@ class MCTargetAsmParser : public MCAsmParserExtension { /// AvailableFeatures - The current set of available features. FeatureBitset AvailableFeatures; - /// ParsingInlineAsm - Are we parsing ms-style inline assembly? - bool ParsingInlineAsm = false; + /// ParsingMSInlineAsm - Are we parsing ms-style inline assembly? + bool ParsingMSInlineAsm = false; /// SemaCallback - The Sema callback implementation. Must be set when parsing /// ms-style inline assembly. @@ -359,8 +359,8 @@ class MCTargetAsmParser : public MCAsmParserExtension { AvailableFeatures = Value; } - bool isParsingInlineAsm () { return ParsingInlineAsm; } - void setParsingInlineAsm (bool Value) { ParsingInlineAsm = Value; } + bool isParsingMSInlineAsm () { return ParsingMSInlineAsm; } + void setParsingMSInlineAsm (bool Value) { ParsingMSInlineAsm = Value; } MCTargetOptions getTargetOptions() const { return MCOptions; } diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index 05c479abb69b..57e152156475 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -174,7 +174,7 @@ class AsmParser : public MCAsmParser { bool IsDarwin = false; /// Are we parsing ms-style inline assembly? - bool ParsingInlineAsm = false; + bool ParsingMSInlineAsm = false; /// Did we already inform the user about inconsistent MD5 usage? bool ReportedInconsistentMD5 = false; @@ -226,13 +226,13 @@ class AsmParser : public MCAsmParser { const AsmToken &Lex() override; - void setParsingInlineAsm(bool V) override { -ParsingInlineAsm = V; + void setParsingMSInlineAsm(bool V) override { +ParsingMSInlineAsm = V; // When parsing MS inline asm, we must lex 0b1101 and 0ABCH as binary and // hex integer literals. Lexer.setLexMasmIntegers(V); } - bool isParsingInlineAsm() override { return ParsingInlineAsm; } + bool isParsingMSInlineAsm() override { return ParsingMSInlineAsm; } bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString, unsigned &NumOutputs, unsigned &NumInputs, @@ -994,7 +994,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { } bool AsmParser::checkForValidSection() { - if (!ParsingInlineAsm && !getStreamer().getCurrentSectionOnly()) { + if (!ParsingMSInli
[clang] be6ac47 - [ms] Fix Microsoft compatibility handling of commas in nested macro expansions.
Author: Eric Astor Date: 2019-11-04T12:49:19-05:00 New Revision: be6ac471f613427f3b5b3a306fe033e526d59f76 URL: https://github.com/llvm/llvm-project/commit/be6ac471f613427f3b5b3a306fe033e526d59f76 DIFF: https://github.com/llvm/llvm-project/commit/be6ac471f613427f3b5b3a306fe033e526d59f76.diff LOG: [ms] Fix Microsoft compatibility handling of commas in nested macro expansions. In Microsoft-compatibility mode, single commas from nested macro expansions should not be considered as argument separators; we already emulated this by marking them to be ignored. However, in MSVC's preprocessor, subsequent expansions DO treat these commas as argument separators... so we now ignore each comma at most once. Includes a small unit test that validates we match MSVC's behavior as shown in https://gcc.godbolt.org/z/y0twaq Fixes PR43282 Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D69626 Added: Modified: clang/lib/Lex/PPMacroExpansion.cpp clang/test/Preprocessor/microsoft-ext.c Removed: diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index dfbcaedcacff..c13515280b7c 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -820,18 +820,26 @@ MacroArgs *Preprocessor::ReadMacroCallArgumentList(Token &MacroName, } } else if (Tok.is(tok::l_paren)) { ++NumParens; - } else if (Tok.is(tok::comma) && NumParens == 0 && - !(Tok.getFlags() & Token::IgnoredComma)) { + } else if (Tok.is(tok::comma)) { // In Microsoft-compatibility mode, single commas from nested macro // expansions should not be considered as argument separators. We test -// for this with the IgnoredComma token flag above. - -// Comma ends this argument if there are more fixed arguments expected. -// However, if this is a variadic macro, and this is part of the -// variadic part, then the comma is just an argument token. -if (!isVariadic) break; -if (NumFixedArgsLeft > 1) - break; +// for this with the IgnoredComma token flag. +if (Tok.getFlags() & Token::IgnoredComma) { + // However, in MSVC's preprocessor, subsequent expansions do treat + // these commas as argument separators. This leads to a common + // workaround used in macros that need to work in both MSVC and + // compliant preprocessors. Therefore, the IgnoredComma flag can only + // apply once to any given token. + Tok.clearFlag(Token::IgnoredComma); +} else if (NumParens == 0) { + // Comma ends this argument if there are more fixed arguments + // expected. However, if this is a variadic macro, and this is part of + // the variadic part, then the comma is just an argument token. + if (!isVariadic) +break; + if (NumFixedArgsLeft > 1) +break; +} } else if (Tok.is(tok::comment) && !KeepMacroComments) { // If this is a comment token in the argument list and we're just in // -C mode (not -CC mode), discard the comment. diff --git a/clang/test/Preprocessor/microsoft-ext.c b/clang/test/Preprocessor/microsoft-ext.c index cb3cf4f15379..aae52a84b62f 100644 --- a/clang/test/Preprocessor/microsoft-ext.c +++ b/clang/test/Preprocessor/microsoft-ext.c @@ -23,6 +23,19 @@ ACTION_TEMPLATE(InvokeArgument, HAS_1_TEMPLATE_PARAMS(int, k), AND_2_VALUE_PARAMS(p0, p1)); +// Regression test for PR43282; check that we match MSVC's failure to unpack +// __VA_ARGS__ unless forwarded through another macro. +#define THIRD_ARGUMENT(A, B, C, ...) C +#define TEST(...) THIRD_ARGUMENT(__VA_ARGS__, 1, 2) +#define COMBINE(...) __VA_ARGS__ +#define WRAPPED_TEST(...) COMBINE(THIRD_ARGUMENT(__VA_ARGS__, 1, 2)) +// Check that we match MSVC's failure to unpack __VA_ARGS__, unless forwarded +// through another macro +auto packed = TEST(,); +auto unpacked = WRAPPED_TEST(,); +// CHECK: auto packed = 2; +// CHECK: auto unpacked = 1; + // This tests compatibility with behaviour needed for type_traits in VS2012 // Test based on _VARIADIC_EXPAND_0X macros in xstddef of VS2012 #define _COMMA , ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] dc5b614 - [ms] [X86] Use "P" modifier on operands to call instructions in inline X86 assembly.
Author: Eric Astor Date: 2019-12-22T09:16:34-05:00 New Revision: dc5b614fa9a1c83e8275fcb9c3f78444d0a30514 URL: https://github.com/llvm/llvm-project/commit/dc5b614fa9a1c83e8275fcb9c3f78444d0a30514 DIFF: https://github.com/llvm/llvm-project/commit/dc5b614fa9a1c83e8275fcb9c3f78444d0a30514.diff LOG: [ms] [X86] Use "P" modifier on operands to call instructions in inline X86 assembly. Summary: This is documented as the appropriate template modifier for call operands. Fixes PR44272, and adds a regression test. Also adds support for operand modifiers in Intel-style inline assembly. Reviewers: rnk Reviewed By: rnk Subscribers: merge_guards_bot, hiraditya, cfe-commits, llvm-commits Tags: #clang, #llvm Differential Revision: https://reviews.llvm.org/D71677 Added: llvm/test/CodeGen/X86/ms-inline-asm-PR44272.ll Modified: clang/lib/CodeGen/TargetInfo.cpp clang/test/CodeGen/mozilla-ms-inline-asm.c clang/test/CodeGen/ms-inline-asm.c clang/test/CodeGen/ms-inline-asm.cpp llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h llvm/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp llvm/lib/MC/MCParser/AsmParser.cpp llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp llvm/lib/Target/X86/AsmParser/X86Operand.h llvm/lib/Target/X86/X86AsmPrinter.cpp llvm/lib/Target/X86/X86AsmPrinter.h Removed: diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 9fd4a5fb17a7..6c6400652a6d 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -1187,6 +1187,10 @@ static void rewriteInputConstraintReferences(unsigned FirstIn, if (NumDollars % 2 != 0 && Pos < AsmString.size()) { // We have an operand reference. size_t DigitStart = Pos; + if (AsmString[DigitStart] == '{') { +OS << '{'; +++DigitStart; + } size_t DigitEnd = AsmString.find_first_not_of("0123456789", DigitStart); if (DigitEnd == std::string::npos) DigitEnd = AsmString.size(); diff --git a/clang/test/CodeGen/mozilla-ms-inline-asm.c b/clang/test/CodeGen/mozilla-ms-inline-asm.c index 0774c8cb3045..210c7f2b9c8e 100644 --- a/clang/test/CodeGen/mozilla-ms-inline-asm.c +++ b/clang/test/CodeGen/mozilla-ms-inline-asm.c @@ -27,7 +27,7 @@ void invoke(void* that, unsigned methodIndex, // CHECK-SAME: sub esp,eax // CHECK-SAME: mov ecx,esp // CHECK-SAME: push $0 -// CHECK-SAME: call dword ptr $2 +// CHECK-SAME: call dword ptr ${2:P} // CHECK-SAME: {{.*}}__MSASMLABEL_.${:uid}__noparams: // CHECK-SAME: mov ecx,$3 // CHECK-SAME: push ecx diff --git a/clang/test/CodeGen/ms-inline-asm.c b/clang/test/CodeGen/ms-inline-asm.c index 00d408f431c4..0c9b35a64523 100644 --- a/clang/test/CodeGen/ms-inline-asm.c +++ b/clang/test/CodeGen/ms-inline-asm.c @@ -306,7 +306,7 @@ void t24_helper(void) {} void t24() { __asm call t24_helper // CHECK: t24 -// CHECK: call void asm sideeffect inteldialect "call dword ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(void ()* @t24_helper) +// CHECK: call void asm sideeffect inteldialect "call dword ptr ${0:P}", "*m,~{dirflag},~{fpsr},~{flags}"(void ()* @t24_helper) } void t25() { @@ -689,7 +689,7 @@ void dot_operator(){ void call_clobber() { __asm call t41 // CHECK-LABEL: define void @call_clobber - // CHECK: call void asm sideeffect inteldialect "call dword ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(void (i16)* @t41) + // CHECK: call void asm sideeffect inteldialect "call dword ptr ${0:P}", "*m,~{dirflag},~{fpsr},~{flags}"(void (i16)* @t41) } void xgetbv() { diff --git a/clang/test/CodeGen/ms-inline-asm.cpp b/clang/test/CodeGen/ms-inline-asm.cpp index 039cde9e10ed..58796ed6378d 100644 --- a/clang/test/CodeGen/ms-inline-asm.cpp +++ b/clang/test/CodeGen/ms-inline-asm.cpp @@ -109,7 +109,7 @@ void test5() { __asm mov x, eax // CHECK: call void asm sideeffect inteldialect // CHECK-SAME: push $0 - // CHECK-SAME: call dword ptr $2 + // CHECK-SAME: call dword ptr ${2:P} // CHECK-SAME: mov $1, eax // CHECK-SAME: "=*m,=*m,*m,~{esp},~{dirflag},~{fpsr},~{flags}"(i32* %y, i32* %x, i32 (float)* @_ZN2T5IiE6createIfEEiT_) } diff --git a/llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h b/llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h index 2b6e2aa48b8f..c3bb8e52e095 100644 --- a/llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h +++ b/llvm/include/llvm/MC/MCParser/MCParsedAsmOperand.h @@ -71,6 +71,10 @@ class MCParsedAsmOperand { /// variable/label? Only valid when parsing MS-style inline assembly. virtual bool needAddressOf() const { return false; } + /// isCallOperand - Is this an operand of an inline-assembly call instruction? + /// Only valid when parsing MS-style inline assembly. + virtual bool isCallOperand() const { return false; } + /// isOffsetOf - Do we need to emit code to get the
[clang] [clang][frontend] Add support for attribute plugins for statement attributes (PR #110334)
@@ -2125,6 +2126,19 @@ TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E, Arg, PackIndex); } +const AnnotateAttr * +TemplateInstantiator::TransformAnnotateAttr(const AnnotateAttr *AA) { + SmallVector Args; + for (Expr *Arg : AA->args()) { +ExprResult Res = getDerived().TransformExpr(Arg); +if (!Res.isUsable()) + return AA; +Args.push_back(Res.get()); + } + return AnnotateAttr::CreateImplicit(getSema().Context, AA->getAnnotation(), ericastor wrote: I think `StringArgument` only handles `StringRef`s? I don't see a way it could be given a dependent value. https://github.com/llvm/llvm-project/pull/110334 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][frontend] Add support for attribute plugins for statement attributes (PR #110334)
https://github.com/ericastor updated https://github.com/llvm/llvm-project/pull/110334 >From 0411b2939e10ca335e84731502126145509bef2d Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Fri, 27 Sep 2024 22:35:28 + Subject: [PATCH 1/3] [clang][frontend] Add support for attribute plugins for statement attributes We already have support for declaration attributes; this is just a matter of extending the plugin infrastructure to cover one more case. --- clang/docs/ClangPlugins.rst| 17 +--- clang/examples/Attribute/Attribute.cpp | 49 ++ clang/include/clang/Basic/ParsedAttrInfo.h | 10 + clang/lib/Sema/SemaStmtAttr.cpp| 4 ++ clang/test/Frontend/plugin-attribute.cpp | 40 ++ 5 files changed, 108 insertions(+), 12 deletions(-) diff --git a/clang/docs/ClangPlugins.rst b/clang/docs/ClangPlugins.rst index 001e66e434efb1..92e41fb5877fe8 100644 --- a/clang/docs/ClangPlugins.rst +++ b/clang/docs/ClangPlugins.rst @@ -92,11 +92,6 @@ The members of ``ParsedAttrInfo`` that a plugin attribute must define are: attribute, each of which consists of an attribute syntax and how the attribute name is spelled for that syntax. If the syntax allows a scope then the spelling must be "scope::attr" if a scope is present or "::attr" if not. - * ``handleDeclAttribute``, which is the function that applies the attribute to - a declaration. It is responsible for checking that the attribute's arguments - are valid, and typically applies the attribute by adding an ``Attr`` to the - ``Decl``. It returns either ``AttributeApplied``, to indicate that the - attribute was successfully applied, or ``AttributeNotApplied`` if it wasn't. The members of ``ParsedAttrInfo`` that may need to be defined, depending on the attribute, are: @@ -105,6 +100,18 @@ attribute, are: arguments to the attribute. * ``diagAppertainsToDecl``, which checks if the attribute has been used on the right kind of declaration and issues a diagnostic if not. + * ``handleDeclAttribute``, which is the function that applies the attribute to + a declaration. It is responsible for checking that the attribute's arguments + are valid, and typically applies the attribute by adding an ``Attr`` to the + ``Decl``. It returns either ``AttributeApplied``, to indicate that the + attribute was successfully applied, or ``AttributeNotApplied`` if it wasn't. + * ``diagAppertainsToStmt``, which checks if the attribute has been used on the + right kind of statement and issues a diagnostic if not. + * ``handleStmtAttribute``, which is the function that applies the attribute to + a statement. It is responsible for checking that the attribute's arguments + are valid, and typically applies the attribute by adding an ``Attr`` to the + ``Stmt``. It returns either ``AttributeApplied``, to indicate that the + attribute was successfully applied, or ``AttributeNotApplied`` if it wasn't. * ``diagLangOpts``, which checks if the attribute is permitted for the current language mode and issues a diagnostic if not. * ``existsInTarget``, which checks if the attribute is permitted for the given diff --git a/clang/examples/Attribute/Attribute.cpp b/clang/examples/Attribute/Attribute.cpp index 9d6cf9ae36c6a6..07dd19321195c8 100644 --- a/clang/examples/Attribute/Attribute.cpp +++ b/clang/examples/Attribute/Attribute.cpp @@ -94,6 +94,55 @@ struct ExampleAttrInfo : public ParsedAttrInfo { } return AttributeApplied; } + + bool diagAppertainsToStmt(Sema &S, const ParsedAttr &Attr, +const Stmt *St) const override { +// This attribute appertains to for loop statements only. +if (!isa(St)) { + S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type_str) + << Attr << Attr.isRegularKeywordAttribute() << "for loop statements"; + return false; +} +return true; + } + + AttrHandling handleStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &Attr, + class Attr *&Result) const override { +// We make some rules here: +// 1. Only accept at most 3 arguments here. +// 2. The first argument must be a string literal if it exists. +if (Attr.getNumArgs() > 3) { + unsigned ID = S.getDiagnostics().getCustomDiagID( + DiagnosticsEngine::Error, + "'example' attribute only accepts at most three arguments"); + S.Diag(Attr.getLoc(), ID); + return AttributeNotApplied; +} +// If there are arguments, the first argument should be a string literal. +if (Attr.getNumArgs() > 0) { + auto *Arg0 = Attr.getArgAsExpr(0); + StringLiteral *Literal = + dyn_cast(Arg0->IgnoreParenCasts()); + if (!Literal) { +unsigned ID = S.getDiagnostics().getCustomDiagID( +DiagnosticsEngine::Error, "first argument to the 'example' " + "attribute must be a string literal"); +S
[clang] [clang][frontend] Add support for attribute plugins for statement attributes (PR #110334)
ericastor wrote: So... I think this turned out to be surprisingly easy. After all, we don't actually allow custom attributes to create entirely new attributes in the AST, since they can't create new legal AST entries... instead, the example creates AnnotateAttrs that can then be observed & acted on by the compiler-extending plugin. It looks like reaching the same level of support just required adding AnnotateAttr support to the template instantiation logic. Am I missing anything else? @erichkeane https://github.com/llvm/llvm-project/pull/110334 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [flang] [libc] [libcxx] [libcxxabi] [libunwind] [lldb] [llvm] [mlir] [clang][frontend] Add support for attribute plugins for statement attributes (PR #110334)
Valentin Clement =?utf-8?b?KOODkOODrOODsw=?=,Renato Golin ,Eric Astor Message-ID: In-Reply-To: https://github.com/ericastor closed https://github.com/llvm/llvm-project/pull/110334 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][frontend] Add support for attribute plugins for statement attributes (PR #110334)
https://github.com/ericastor updated https://github.com/llvm/llvm-project/pull/110334 >From 0411b2939e10ca335e84731502126145509bef2d Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Fri, 27 Sep 2024 22:35:28 + Subject: [PATCH 1/3] [clang][frontend] Add support for attribute plugins for statement attributes We already have support for declaration attributes; this is just a matter of extending the plugin infrastructure to cover one more case. --- clang/docs/ClangPlugins.rst| 17 +--- clang/examples/Attribute/Attribute.cpp | 49 ++ clang/include/clang/Basic/ParsedAttrInfo.h | 10 + clang/lib/Sema/SemaStmtAttr.cpp| 4 ++ clang/test/Frontend/plugin-attribute.cpp | 40 ++ 5 files changed, 108 insertions(+), 12 deletions(-) diff --git a/clang/docs/ClangPlugins.rst b/clang/docs/ClangPlugins.rst index 001e66e434efb1..92e41fb5877fe8 100644 --- a/clang/docs/ClangPlugins.rst +++ b/clang/docs/ClangPlugins.rst @@ -92,11 +92,6 @@ The members of ``ParsedAttrInfo`` that a plugin attribute must define are: attribute, each of which consists of an attribute syntax and how the attribute name is spelled for that syntax. If the syntax allows a scope then the spelling must be "scope::attr" if a scope is present or "::attr" if not. - * ``handleDeclAttribute``, which is the function that applies the attribute to - a declaration. It is responsible for checking that the attribute's arguments - are valid, and typically applies the attribute by adding an ``Attr`` to the - ``Decl``. It returns either ``AttributeApplied``, to indicate that the - attribute was successfully applied, or ``AttributeNotApplied`` if it wasn't. The members of ``ParsedAttrInfo`` that may need to be defined, depending on the attribute, are: @@ -105,6 +100,18 @@ attribute, are: arguments to the attribute. * ``diagAppertainsToDecl``, which checks if the attribute has been used on the right kind of declaration and issues a diagnostic if not. + * ``handleDeclAttribute``, which is the function that applies the attribute to + a declaration. It is responsible for checking that the attribute's arguments + are valid, and typically applies the attribute by adding an ``Attr`` to the + ``Decl``. It returns either ``AttributeApplied``, to indicate that the + attribute was successfully applied, or ``AttributeNotApplied`` if it wasn't. + * ``diagAppertainsToStmt``, which checks if the attribute has been used on the + right kind of statement and issues a diagnostic if not. + * ``handleStmtAttribute``, which is the function that applies the attribute to + a statement. It is responsible for checking that the attribute's arguments + are valid, and typically applies the attribute by adding an ``Attr`` to the + ``Stmt``. It returns either ``AttributeApplied``, to indicate that the + attribute was successfully applied, or ``AttributeNotApplied`` if it wasn't. * ``diagLangOpts``, which checks if the attribute is permitted for the current language mode and issues a diagnostic if not. * ``existsInTarget``, which checks if the attribute is permitted for the given diff --git a/clang/examples/Attribute/Attribute.cpp b/clang/examples/Attribute/Attribute.cpp index 9d6cf9ae36c6a6..07dd19321195c8 100644 --- a/clang/examples/Attribute/Attribute.cpp +++ b/clang/examples/Attribute/Attribute.cpp @@ -94,6 +94,55 @@ struct ExampleAttrInfo : public ParsedAttrInfo { } return AttributeApplied; } + + bool diagAppertainsToStmt(Sema &S, const ParsedAttr &Attr, +const Stmt *St) const override { +// This attribute appertains to for loop statements only. +if (!isa(St)) { + S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type_str) + << Attr << Attr.isRegularKeywordAttribute() << "for loop statements"; + return false; +} +return true; + } + + AttrHandling handleStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &Attr, + class Attr *&Result) const override { +// We make some rules here: +// 1. Only accept at most 3 arguments here. +// 2. The first argument must be a string literal if it exists. +if (Attr.getNumArgs() > 3) { + unsigned ID = S.getDiagnostics().getCustomDiagID( + DiagnosticsEngine::Error, + "'example' attribute only accepts at most three arguments"); + S.Diag(Attr.getLoc(), ID); + return AttributeNotApplied; +} +// If there are arguments, the first argument should be a string literal. +if (Attr.getNumArgs() > 0) { + auto *Arg0 = Attr.getArgAsExpr(0); + StringLiteral *Literal = + dyn_cast(Arg0->IgnoreParenCasts()); + if (!Literal) { +unsigned ID = S.getDiagnostics().getCustomDiagID( +DiagnosticsEngine::Error, "first argument to the 'example' " + "attribute must be a string literal"); +S
[clang] [clang][frontend] Support applying the annotate attribute to statements (PR #111841)
https://github.com/ericastor updated https://github.com/llvm/llvm-project/pull/111841 >From 6ca0de7e07a02a91ed9ea1493e48c2d29806c537 Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Wed, 9 Oct 2024 22:12:50 + Subject: [PATCH 1/3] [clang][frontend] Support applying annotate to statements The underlying code already works; this is just a matter of allowing application of this undocumented attribute. --- clang/include/clang/Basic/Attr.td | 7 ++- clang/utils/TableGen/ClangAttrEmitter.cpp | 11 +++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index fbcbf0ed416416..ec3d6e0079f630 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -759,6 +759,11 @@ class TargetSpecificAttr { /// redeclarations, even when it's written on a parameter. class InheritableParamAttr : InheritableAttr; +/// A attribute that is either a declaration attribute or a statement attribute, +/// and if used as a declaration attribute, is inherited by later +/// redeclarations, even when it's written on a parameter. +class InheritableParamOrStmtAttr : InheritableParamAttr; + /// An attribute which changes the ABI rules for a specific parameter. class ParameterABIAttr : InheritableParamAttr { let Subjects = SubjectList<[ParmVar]>; @@ -928,7 +933,7 @@ def AnalyzerNoReturn : InheritableAttr { let Documentation = [Undocumented]; } -def Annotate : InheritableParamAttr { +def Annotate : InheritableParamOrStmtAttr { let Spellings = [Clang<"annotate">]; let Args = [StringArgument<"Annotation">, VariadicExprArgument<"Args">]; // Ensure that the annotate attribute can be used with diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index 87be48c215e230..cee47fa8a283f2 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -3295,6 +3295,7 @@ static const AttrClassDescriptor AttrClassDescriptors[] = { { "INHERITABLE_ATTR", "InheritableAttr" }, { "DECL_OR_TYPE_ATTR", "DeclOrTypeAttr" }, { "INHERITABLE_PARAM_ATTR", "InheritableParamAttr" }, + { "INHERITABLE_PARAM_OR_STMT_ATTR", "InheritableParamOrStmtAttr" }, { "PARAMETER_ABI_ATTR", "ParameterABIAttr" }, { "HLSL_ANNOTATION_ATTR", "HLSLAnnotationAttr"} }; @@ -4328,10 +4329,12 @@ static void GenerateMutualExclusionsChecks(const Record &Attr, // This means the attribute is either a statement attribute, a decl // attribute, or both; find out which. - bool CurAttrIsStmtAttr = - Attr.isSubClassOf("StmtAttr") || Attr.isSubClassOf("DeclOrStmtAttr"); - bool CurAttrIsDeclAttr = - !CurAttrIsStmtAttr || Attr.isSubClassOf("DeclOrStmtAttr"); + bool CurAttrIsStmtAttr = Attr.isSubClassOf("StmtAttr") || + Attr.isSubClassOf("DeclOrStmtAttr") || + Attr.isSubClassOf("InheritableParamOrStmtAttr"); + bool CurAttrIsDeclAttr = !CurAttrIsStmtAttr || + Attr.isSubClassOf("DeclOrStmtAttr") || + Attr.isSubClassOf("InheritableParamOrStmtAttr"); std::vector DeclAttrs, StmtAttrs; >From 88e7bf70c327b85bcbd595503a593de80676d1b4 Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Thu, 10 Oct 2024 14:10:52 + Subject: [PATCH 2/3] Add additional support for stmt-level AnnotateAttr --- clang/include/clang/AST/Attr.h | 17 ++ clang/lib/Sema/SemaStmtAttr.cpp| 20 clang/lib/Sema/SemaTemplateInstantiate.cpp | 14 clang/test/AST/attr-print-emit.cpp | 3 ++ clang/test/Sema/annotate.c | 3 ++ clang/test/SemaTemplate/attributes.cpp | 38 ++ 6 files changed, 95 insertions(+) diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h index ac44e9fdd7c4e9..725498e132fc28 100644 --- a/clang/include/clang/AST/Attr.h +++ b/clang/include/clang/AST/Attr.h @@ -197,6 +197,23 @@ class InheritableParamAttr : public InheritableAttr { } }; +class InheritableParamOrStmtAttr : public InheritableParamAttr { +protected: + InheritableParamOrStmtAttr(ASTContext &Context, + const AttributeCommonInfo &CommonInfo, + attr::Kind AK, bool IsLateParsed, + bool InheritEvenIfAlreadyPresent) + : InheritableParamAttr(Context, CommonInfo, AK, IsLateParsed, + InheritEvenIfAlreadyPresent) {} + +public: + // Implement isa/cast/dyncast/etc. + static bool classof(const Attr *A) { +return A->getKind() >= attr::FirstInheritableParamOrStmtAttr && + A->getKind() <= attr::LastInheritableParamOrStmtAttr; + } +}; + class HLSLAnnotationAttr : public InheritableAttr { protected: HLSLAnnotationAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo, diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/c
[clang] [clang][frontend] Support applying the annotate attribute to statements (PR #111841)
https://github.com/ericastor updated https://github.com/llvm/llvm-project/pull/111841 >From 6ca0de7e07a02a91ed9ea1493e48c2d29806c537 Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Wed, 9 Oct 2024 22:12:50 + Subject: [PATCH 1/4] [clang][frontend] Support applying annotate to statements The underlying code already works; this is just a matter of allowing application of this undocumented attribute. --- clang/include/clang/Basic/Attr.td | 7 ++- clang/utils/TableGen/ClangAttrEmitter.cpp | 11 +++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index fbcbf0ed416416..ec3d6e0079f630 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -759,6 +759,11 @@ class TargetSpecificAttr { /// redeclarations, even when it's written on a parameter. class InheritableParamAttr : InheritableAttr; +/// A attribute that is either a declaration attribute or a statement attribute, +/// and if used as a declaration attribute, is inherited by later +/// redeclarations, even when it's written on a parameter. +class InheritableParamOrStmtAttr : InheritableParamAttr; + /// An attribute which changes the ABI rules for a specific parameter. class ParameterABIAttr : InheritableParamAttr { let Subjects = SubjectList<[ParmVar]>; @@ -928,7 +933,7 @@ def AnalyzerNoReturn : InheritableAttr { let Documentation = [Undocumented]; } -def Annotate : InheritableParamAttr { +def Annotate : InheritableParamOrStmtAttr { let Spellings = [Clang<"annotate">]; let Args = [StringArgument<"Annotation">, VariadicExprArgument<"Args">]; // Ensure that the annotate attribute can be used with diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index 87be48c215e230..cee47fa8a283f2 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -3295,6 +3295,7 @@ static const AttrClassDescriptor AttrClassDescriptors[] = { { "INHERITABLE_ATTR", "InheritableAttr" }, { "DECL_OR_TYPE_ATTR", "DeclOrTypeAttr" }, { "INHERITABLE_PARAM_ATTR", "InheritableParamAttr" }, + { "INHERITABLE_PARAM_OR_STMT_ATTR", "InheritableParamOrStmtAttr" }, { "PARAMETER_ABI_ATTR", "ParameterABIAttr" }, { "HLSL_ANNOTATION_ATTR", "HLSLAnnotationAttr"} }; @@ -4328,10 +4329,12 @@ static void GenerateMutualExclusionsChecks(const Record &Attr, // This means the attribute is either a statement attribute, a decl // attribute, or both; find out which. - bool CurAttrIsStmtAttr = - Attr.isSubClassOf("StmtAttr") || Attr.isSubClassOf("DeclOrStmtAttr"); - bool CurAttrIsDeclAttr = - !CurAttrIsStmtAttr || Attr.isSubClassOf("DeclOrStmtAttr"); + bool CurAttrIsStmtAttr = Attr.isSubClassOf("StmtAttr") || + Attr.isSubClassOf("DeclOrStmtAttr") || + Attr.isSubClassOf("InheritableParamOrStmtAttr"); + bool CurAttrIsDeclAttr = !CurAttrIsStmtAttr || + Attr.isSubClassOf("DeclOrStmtAttr") || + Attr.isSubClassOf("InheritableParamOrStmtAttr"); std::vector DeclAttrs, StmtAttrs; >From 88e7bf70c327b85bcbd595503a593de80676d1b4 Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Thu, 10 Oct 2024 14:10:52 + Subject: [PATCH 2/4] Add additional support for stmt-level AnnotateAttr --- clang/include/clang/AST/Attr.h | 17 ++ clang/lib/Sema/SemaStmtAttr.cpp| 20 clang/lib/Sema/SemaTemplateInstantiate.cpp | 14 clang/test/AST/attr-print-emit.cpp | 3 ++ clang/test/Sema/annotate.c | 3 ++ clang/test/SemaTemplate/attributes.cpp | 38 ++ 6 files changed, 95 insertions(+) diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h index ac44e9fdd7c4e9..725498e132fc28 100644 --- a/clang/include/clang/AST/Attr.h +++ b/clang/include/clang/AST/Attr.h @@ -197,6 +197,23 @@ class InheritableParamAttr : public InheritableAttr { } }; +class InheritableParamOrStmtAttr : public InheritableParamAttr { +protected: + InheritableParamOrStmtAttr(ASTContext &Context, + const AttributeCommonInfo &CommonInfo, + attr::Kind AK, bool IsLateParsed, + bool InheritEvenIfAlreadyPresent) + : InheritableParamAttr(Context, CommonInfo, AK, IsLateParsed, + InheritEvenIfAlreadyPresent) {} + +public: + // Implement isa/cast/dyncast/etc. + static bool classof(const Attr *A) { +return A->getKind() >= attr::FirstInheritableParamOrStmtAttr && + A->getKind() <= attr::LastInheritableParamOrStmtAttr; + } +}; + class HLSLAnnotationAttr : public InheritableAttr { protected: HLSLAnnotationAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo, diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/c
[clang] [clang][frontend] Support applying the annotate attribute to statements (PR #111841)
https://github.com/ericastor updated https://github.com/llvm/llvm-project/pull/111841 >From 6ca0de7e07a02a91ed9ea1493e48c2d29806c537 Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Wed, 9 Oct 2024 22:12:50 + Subject: [PATCH 1/4] [clang][frontend] Support applying annotate to statements The underlying code already works; this is just a matter of allowing application of this undocumented attribute. --- clang/include/clang/Basic/Attr.td | 7 ++- clang/utils/TableGen/ClangAttrEmitter.cpp | 11 +++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index fbcbf0ed416416..ec3d6e0079f630 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -759,6 +759,11 @@ class TargetSpecificAttr { /// redeclarations, even when it's written on a parameter. class InheritableParamAttr : InheritableAttr; +/// A attribute that is either a declaration attribute or a statement attribute, +/// and if used as a declaration attribute, is inherited by later +/// redeclarations, even when it's written on a parameter. +class InheritableParamOrStmtAttr : InheritableParamAttr; + /// An attribute which changes the ABI rules for a specific parameter. class ParameterABIAttr : InheritableParamAttr { let Subjects = SubjectList<[ParmVar]>; @@ -928,7 +933,7 @@ def AnalyzerNoReturn : InheritableAttr { let Documentation = [Undocumented]; } -def Annotate : InheritableParamAttr { +def Annotate : InheritableParamOrStmtAttr { let Spellings = [Clang<"annotate">]; let Args = [StringArgument<"Annotation">, VariadicExprArgument<"Args">]; // Ensure that the annotate attribute can be used with diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index 87be48c215e230..cee47fa8a283f2 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -3295,6 +3295,7 @@ static const AttrClassDescriptor AttrClassDescriptors[] = { { "INHERITABLE_ATTR", "InheritableAttr" }, { "DECL_OR_TYPE_ATTR", "DeclOrTypeAttr" }, { "INHERITABLE_PARAM_ATTR", "InheritableParamAttr" }, + { "INHERITABLE_PARAM_OR_STMT_ATTR", "InheritableParamOrStmtAttr" }, { "PARAMETER_ABI_ATTR", "ParameterABIAttr" }, { "HLSL_ANNOTATION_ATTR", "HLSLAnnotationAttr"} }; @@ -4328,10 +4329,12 @@ static void GenerateMutualExclusionsChecks(const Record &Attr, // This means the attribute is either a statement attribute, a decl // attribute, or both; find out which. - bool CurAttrIsStmtAttr = - Attr.isSubClassOf("StmtAttr") || Attr.isSubClassOf("DeclOrStmtAttr"); - bool CurAttrIsDeclAttr = - !CurAttrIsStmtAttr || Attr.isSubClassOf("DeclOrStmtAttr"); + bool CurAttrIsStmtAttr = Attr.isSubClassOf("StmtAttr") || + Attr.isSubClassOf("DeclOrStmtAttr") || + Attr.isSubClassOf("InheritableParamOrStmtAttr"); + bool CurAttrIsDeclAttr = !CurAttrIsStmtAttr || + Attr.isSubClassOf("DeclOrStmtAttr") || + Attr.isSubClassOf("InheritableParamOrStmtAttr"); std::vector DeclAttrs, StmtAttrs; >From 88e7bf70c327b85bcbd595503a593de80676d1b4 Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Thu, 10 Oct 2024 14:10:52 + Subject: [PATCH 2/4] Add additional support for stmt-level AnnotateAttr --- clang/include/clang/AST/Attr.h | 17 ++ clang/lib/Sema/SemaStmtAttr.cpp| 20 clang/lib/Sema/SemaTemplateInstantiate.cpp | 14 clang/test/AST/attr-print-emit.cpp | 3 ++ clang/test/Sema/annotate.c | 3 ++ clang/test/SemaTemplate/attributes.cpp | 38 ++ 6 files changed, 95 insertions(+) diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h index ac44e9fdd7c4e9..725498e132fc28 100644 --- a/clang/include/clang/AST/Attr.h +++ b/clang/include/clang/AST/Attr.h @@ -197,6 +197,23 @@ class InheritableParamAttr : public InheritableAttr { } }; +class InheritableParamOrStmtAttr : public InheritableParamAttr { +protected: + InheritableParamOrStmtAttr(ASTContext &Context, + const AttributeCommonInfo &CommonInfo, + attr::Kind AK, bool IsLateParsed, + bool InheritEvenIfAlreadyPresent) + : InheritableParamAttr(Context, CommonInfo, AK, IsLateParsed, + InheritEvenIfAlreadyPresent) {} + +public: + // Implement isa/cast/dyncast/etc. + static bool classof(const Attr *A) { +return A->getKind() >= attr::FirstInheritableParamOrStmtAttr && + A->getKind() <= attr::LastInheritableParamOrStmtAttr; + } +}; + class HLSLAnnotationAttr : public InheritableAttr { protected: HLSLAnnotationAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo, diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/c
[clang] [clang][frontend] Add support for attribute plugins for statement attributes (PR #110334)
https://github.com/ericastor updated https://github.com/llvm/llvm-project/pull/110334 >From 0411b2939e10ca335e84731502126145509bef2d Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Fri, 27 Sep 2024 22:35:28 + Subject: [PATCH 1/3] [clang][frontend] Add support for attribute plugins for statement attributes We already have support for declaration attributes; this is just a matter of extending the plugin infrastructure to cover one more case. --- clang/docs/ClangPlugins.rst| 17 +--- clang/examples/Attribute/Attribute.cpp | 49 ++ clang/include/clang/Basic/ParsedAttrInfo.h | 10 + clang/lib/Sema/SemaStmtAttr.cpp| 4 ++ clang/test/Frontend/plugin-attribute.cpp | 40 ++ 5 files changed, 108 insertions(+), 12 deletions(-) diff --git a/clang/docs/ClangPlugins.rst b/clang/docs/ClangPlugins.rst index 001e66e434efb1..92e41fb5877fe8 100644 --- a/clang/docs/ClangPlugins.rst +++ b/clang/docs/ClangPlugins.rst @@ -92,11 +92,6 @@ The members of ``ParsedAttrInfo`` that a plugin attribute must define are: attribute, each of which consists of an attribute syntax and how the attribute name is spelled for that syntax. If the syntax allows a scope then the spelling must be "scope::attr" if a scope is present or "::attr" if not. - * ``handleDeclAttribute``, which is the function that applies the attribute to - a declaration. It is responsible for checking that the attribute's arguments - are valid, and typically applies the attribute by adding an ``Attr`` to the - ``Decl``. It returns either ``AttributeApplied``, to indicate that the - attribute was successfully applied, or ``AttributeNotApplied`` if it wasn't. The members of ``ParsedAttrInfo`` that may need to be defined, depending on the attribute, are: @@ -105,6 +100,18 @@ attribute, are: arguments to the attribute. * ``diagAppertainsToDecl``, which checks if the attribute has been used on the right kind of declaration and issues a diagnostic if not. + * ``handleDeclAttribute``, which is the function that applies the attribute to + a declaration. It is responsible for checking that the attribute's arguments + are valid, and typically applies the attribute by adding an ``Attr`` to the + ``Decl``. It returns either ``AttributeApplied``, to indicate that the + attribute was successfully applied, or ``AttributeNotApplied`` if it wasn't. + * ``diagAppertainsToStmt``, which checks if the attribute has been used on the + right kind of statement and issues a diagnostic if not. + * ``handleStmtAttribute``, which is the function that applies the attribute to + a statement. It is responsible for checking that the attribute's arguments + are valid, and typically applies the attribute by adding an ``Attr`` to the + ``Stmt``. It returns either ``AttributeApplied``, to indicate that the + attribute was successfully applied, or ``AttributeNotApplied`` if it wasn't. * ``diagLangOpts``, which checks if the attribute is permitted for the current language mode and issues a diagnostic if not. * ``existsInTarget``, which checks if the attribute is permitted for the given diff --git a/clang/examples/Attribute/Attribute.cpp b/clang/examples/Attribute/Attribute.cpp index 9d6cf9ae36c6a6..07dd19321195c8 100644 --- a/clang/examples/Attribute/Attribute.cpp +++ b/clang/examples/Attribute/Attribute.cpp @@ -94,6 +94,55 @@ struct ExampleAttrInfo : public ParsedAttrInfo { } return AttributeApplied; } + + bool diagAppertainsToStmt(Sema &S, const ParsedAttr &Attr, +const Stmt *St) const override { +// This attribute appertains to for loop statements only. +if (!isa(St)) { + S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type_str) + << Attr << Attr.isRegularKeywordAttribute() << "for loop statements"; + return false; +} +return true; + } + + AttrHandling handleStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &Attr, + class Attr *&Result) const override { +// We make some rules here: +// 1. Only accept at most 3 arguments here. +// 2. The first argument must be a string literal if it exists. +if (Attr.getNumArgs() > 3) { + unsigned ID = S.getDiagnostics().getCustomDiagID( + DiagnosticsEngine::Error, + "'example' attribute only accepts at most three arguments"); + S.Diag(Attr.getLoc(), ID); + return AttributeNotApplied; +} +// If there are arguments, the first argument should be a string literal. +if (Attr.getNumArgs() > 0) { + auto *Arg0 = Attr.getArgAsExpr(0); + StringLiteral *Literal = + dyn_cast(Arg0->IgnoreParenCasts()); + if (!Literal) { +unsigned ID = S.getDiagnostics().getCustomDiagID( +DiagnosticsEngine::Error, "first argument to the 'example' " + "attribute must be a string literal"); +S
[clang] [clang][frontend] Support applying the annotate attribute to statements (PR #111841)
https://github.com/ericastor updated https://github.com/llvm/llvm-project/pull/111841 >From 6ca0de7e07a02a91ed9ea1493e48c2d29806c537 Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Wed, 9 Oct 2024 22:12:50 + Subject: [PATCH 1/5] [clang][frontend] Support applying annotate to statements The underlying code already works; this is just a matter of allowing application of this undocumented attribute. --- clang/include/clang/Basic/Attr.td | 7 ++- clang/utils/TableGen/ClangAttrEmitter.cpp | 11 +++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index fbcbf0ed416416..ec3d6e0079f630 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -759,6 +759,11 @@ class TargetSpecificAttr { /// redeclarations, even when it's written on a parameter. class InheritableParamAttr : InheritableAttr; +/// A attribute that is either a declaration attribute or a statement attribute, +/// and if used as a declaration attribute, is inherited by later +/// redeclarations, even when it's written on a parameter. +class InheritableParamOrStmtAttr : InheritableParamAttr; + /// An attribute which changes the ABI rules for a specific parameter. class ParameterABIAttr : InheritableParamAttr { let Subjects = SubjectList<[ParmVar]>; @@ -928,7 +933,7 @@ def AnalyzerNoReturn : InheritableAttr { let Documentation = [Undocumented]; } -def Annotate : InheritableParamAttr { +def Annotate : InheritableParamOrStmtAttr { let Spellings = [Clang<"annotate">]; let Args = [StringArgument<"Annotation">, VariadicExprArgument<"Args">]; // Ensure that the annotate attribute can be used with diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index 87be48c215e230..cee47fa8a283f2 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -3295,6 +3295,7 @@ static const AttrClassDescriptor AttrClassDescriptors[] = { { "INHERITABLE_ATTR", "InheritableAttr" }, { "DECL_OR_TYPE_ATTR", "DeclOrTypeAttr" }, { "INHERITABLE_PARAM_ATTR", "InheritableParamAttr" }, + { "INHERITABLE_PARAM_OR_STMT_ATTR", "InheritableParamOrStmtAttr" }, { "PARAMETER_ABI_ATTR", "ParameterABIAttr" }, { "HLSL_ANNOTATION_ATTR", "HLSLAnnotationAttr"} }; @@ -4328,10 +4329,12 @@ static void GenerateMutualExclusionsChecks(const Record &Attr, // This means the attribute is either a statement attribute, a decl // attribute, or both; find out which. - bool CurAttrIsStmtAttr = - Attr.isSubClassOf("StmtAttr") || Attr.isSubClassOf("DeclOrStmtAttr"); - bool CurAttrIsDeclAttr = - !CurAttrIsStmtAttr || Attr.isSubClassOf("DeclOrStmtAttr"); + bool CurAttrIsStmtAttr = Attr.isSubClassOf("StmtAttr") || + Attr.isSubClassOf("DeclOrStmtAttr") || + Attr.isSubClassOf("InheritableParamOrStmtAttr"); + bool CurAttrIsDeclAttr = !CurAttrIsStmtAttr || + Attr.isSubClassOf("DeclOrStmtAttr") || + Attr.isSubClassOf("InheritableParamOrStmtAttr"); std::vector DeclAttrs, StmtAttrs; >From 88e7bf70c327b85bcbd595503a593de80676d1b4 Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Thu, 10 Oct 2024 14:10:52 + Subject: [PATCH 2/5] Add additional support for stmt-level AnnotateAttr --- clang/include/clang/AST/Attr.h | 17 ++ clang/lib/Sema/SemaStmtAttr.cpp| 20 clang/lib/Sema/SemaTemplateInstantiate.cpp | 14 clang/test/AST/attr-print-emit.cpp | 3 ++ clang/test/Sema/annotate.c | 3 ++ clang/test/SemaTemplate/attributes.cpp | 38 ++ 6 files changed, 95 insertions(+) diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h index ac44e9fdd7c4e9..725498e132fc28 100644 --- a/clang/include/clang/AST/Attr.h +++ b/clang/include/clang/AST/Attr.h @@ -197,6 +197,23 @@ class InheritableParamAttr : public InheritableAttr { } }; +class InheritableParamOrStmtAttr : public InheritableParamAttr { +protected: + InheritableParamOrStmtAttr(ASTContext &Context, + const AttributeCommonInfo &CommonInfo, + attr::Kind AK, bool IsLateParsed, + bool InheritEvenIfAlreadyPresent) + : InheritableParamAttr(Context, CommonInfo, AK, IsLateParsed, + InheritEvenIfAlreadyPresent) {} + +public: + // Implement isa/cast/dyncast/etc. + static bool classof(const Attr *A) { +return A->getKind() >= attr::FirstInheritableParamOrStmtAttr && + A->getKind() <= attr::LastInheritableParamOrStmtAttr; + } +}; + class HLSLAnnotationAttr : public InheritableAttr { protected: HLSLAnnotationAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo, diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/c
[clang] [clang][frontend] Support applying the annotate attribute to statements (PR #111841)
https://github.com/ericastor created https://github.com/llvm/llvm-project/pull/111841 By allowing AnnotateAttr to be applied to statements, users can place arbitrary information in the AST for later use. For example, this can be used for HW-targeted language extensions that involve specialized loop annotations. >From 6ca0de7e07a02a91ed9ea1493e48c2d29806c537 Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Wed, 9 Oct 2024 22:12:50 + Subject: [PATCH 1/2] [clang][frontend] Support applying annotate to statements The underlying code already works; this is just a matter of allowing application of this undocumented attribute. --- clang/include/clang/Basic/Attr.td | 7 ++- clang/utils/TableGen/ClangAttrEmitter.cpp | 11 +++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index fbcbf0ed416416..ec3d6e0079f630 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -759,6 +759,11 @@ class TargetSpecificAttr { /// redeclarations, even when it's written on a parameter. class InheritableParamAttr : InheritableAttr; +/// A attribute that is either a declaration attribute or a statement attribute, +/// and if used as a declaration attribute, is inherited by later +/// redeclarations, even when it's written on a parameter. +class InheritableParamOrStmtAttr : InheritableParamAttr; + /// An attribute which changes the ABI rules for a specific parameter. class ParameterABIAttr : InheritableParamAttr { let Subjects = SubjectList<[ParmVar]>; @@ -928,7 +933,7 @@ def AnalyzerNoReturn : InheritableAttr { let Documentation = [Undocumented]; } -def Annotate : InheritableParamAttr { +def Annotate : InheritableParamOrStmtAttr { let Spellings = [Clang<"annotate">]; let Args = [StringArgument<"Annotation">, VariadicExprArgument<"Args">]; // Ensure that the annotate attribute can be used with diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index 87be48c215e230..cee47fa8a283f2 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -3295,6 +3295,7 @@ static const AttrClassDescriptor AttrClassDescriptors[] = { { "INHERITABLE_ATTR", "InheritableAttr" }, { "DECL_OR_TYPE_ATTR", "DeclOrTypeAttr" }, { "INHERITABLE_PARAM_ATTR", "InheritableParamAttr" }, + { "INHERITABLE_PARAM_OR_STMT_ATTR", "InheritableParamOrStmtAttr" }, { "PARAMETER_ABI_ATTR", "ParameterABIAttr" }, { "HLSL_ANNOTATION_ATTR", "HLSLAnnotationAttr"} }; @@ -4328,10 +4329,12 @@ static void GenerateMutualExclusionsChecks(const Record &Attr, // This means the attribute is either a statement attribute, a decl // attribute, or both; find out which. - bool CurAttrIsStmtAttr = - Attr.isSubClassOf("StmtAttr") || Attr.isSubClassOf("DeclOrStmtAttr"); - bool CurAttrIsDeclAttr = - !CurAttrIsStmtAttr || Attr.isSubClassOf("DeclOrStmtAttr"); + bool CurAttrIsStmtAttr = Attr.isSubClassOf("StmtAttr") || + Attr.isSubClassOf("DeclOrStmtAttr") || + Attr.isSubClassOf("InheritableParamOrStmtAttr"); + bool CurAttrIsDeclAttr = !CurAttrIsStmtAttr || + Attr.isSubClassOf("DeclOrStmtAttr") || + Attr.isSubClassOf("InheritableParamOrStmtAttr"); std::vector DeclAttrs, StmtAttrs; >From 88e7bf70c327b85bcbd595503a593de80676d1b4 Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Thu, 10 Oct 2024 14:10:52 + Subject: [PATCH 2/2] Add additional support for stmt-level AnnotateAttr --- clang/include/clang/AST/Attr.h | 17 ++ clang/lib/Sema/SemaStmtAttr.cpp| 20 clang/lib/Sema/SemaTemplateInstantiate.cpp | 14 clang/test/AST/attr-print-emit.cpp | 3 ++ clang/test/Sema/annotate.c | 3 ++ clang/test/SemaTemplate/attributes.cpp | 38 ++ 6 files changed, 95 insertions(+) diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h index ac44e9fdd7c4e9..725498e132fc28 100644 --- a/clang/include/clang/AST/Attr.h +++ b/clang/include/clang/AST/Attr.h @@ -197,6 +197,23 @@ class InheritableParamAttr : public InheritableAttr { } }; +class InheritableParamOrStmtAttr : public InheritableParamAttr { +protected: + InheritableParamOrStmtAttr(ASTContext &Context, + const AttributeCommonInfo &CommonInfo, + attr::Kind AK, bool IsLateParsed, + bool InheritEvenIfAlreadyPresent) + : InheritableParamAttr(Context, CommonInfo, AK, IsLateParsed, + InheritEvenIfAlreadyPresent) {} + +public: + // Implement isa/cast/dyncast/etc. + static bool classof(const Attr *A) { +return A->getKind() >= attr::FirstInheritableParamOrStmtAttr && + A->getKind() <= attr::LastInhe
[clang] [clang][frontend] Support applying the annotate attribute to statements (PR #111841)
https://github.com/ericastor updated https://github.com/llvm/llvm-project/pull/111841 >From 6ca0de7e07a02a91ed9ea1493e48c2d29806c537 Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Wed, 9 Oct 2024 22:12:50 + Subject: [PATCH 1/6] [clang][frontend] Support applying annotate to statements The underlying code already works; this is just a matter of allowing application of this undocumented attribute. --- clang/include/clang/Basic/Attr.td | 7 ++- clang/utils/TableGen/ClangAttrEmitter.cpp | 11 +++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index fbcbf0ed416416..ec3d6e0079f630 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -759,6 +759,11 @@ class TargetSpecificAttr { /// redeclarations, even when it's written on a parameter. class InheritableParamAttr : InheritableAttr; +/// A attribute that is either a declaration attribute or a statement attribute, +/// and if used as a declaration attribute, is inherited by later +/// redeclarations, even when it's written on a parameter. +class InheritableParamOrStmtAttr : InheritableParamAttr; + /// An attribute which changes the ABI rules for a specific parameter. class ParameterABIAttr : InheritableParamAttr { let Subjects = SubjectList<[ParmVar]>; @@ -928,7 +933,7 @@ def AnalyzerNoReturn : InheritableAttr { let Documentation = [Undocumented]; } -def Annotate : InheritableParamAttr { +def Annotate : InheritableParamOrStmtAttr { let Spellings = [Clang<"annotate">]; let Args = [StringArgument<"Annotation">, VariadicExprArgument<"Args">]; // Ensure that the annotate attribute can be used with diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index 87be48c215e230..cee47fa8a283f2 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -3295,6 +3295,7 @@ static const AttrClassDescriptor AttrClassDescriptors[] = { { "INHERITABLE_ATTR", "InheritableAttr" }, { "DECL_OR_TYPE_ATTR", "DeclOrTypeAttr" }, { "INHERITABLE_PARAM_ATTR", "InheritableParamAttr" }, + { "INHERITABLE_PARAM_OR_STMT_ATTR", "InheritableParamOrStmtAttr" }, { "PARAMETER_ABI_ATTR", "ParameterABIAttr" }, { "HLSL_ANNOTATION_ATTR", "HLSLAnnotationAttr"} }; @@ -4328,10 +4329,12 @@ static void GenerateMutualExclusionsChecks(const Record &Attr, // This means the attribute is either a statement attribute, a decl // attribute, or both; find out which. - bool CurAttrIsStmtAttr = - Attr.isSubClassOf("StmtAttr") || Attr.isSubClassOf("DeclOrStmtAttr"); - bool CurAttrIsDeclAttr = - !CurAttrIsStmtAttr || Attr.isSubClassOf("DeclOrStmtAttr"); + bool CurAttrIsStmtAttr = Attr.isSubClassOf("StmtAttr") || + Attr.isSubClassOf("DeclOrStmtAttr") || + Attr.isSubClassOf("InheritableParamOrStmtAttr"); + bool CurAttrIsDeclAttr = !CurAttrIsStmtAttr || + Attr.isSubClassOf("DeclOrStmtAttr") || + Attr.isSubClassOf("InheritableParamOrStmtAttr"); std::vector DeclAttrs, StmtAttrs; >From 88e7bf70c327b85bcbd595503a593de80676d1b4 Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Thu, 10 Oct 2024 14:10:52 + Subject: [PATCH 2/6] Add additional support for stmt-level AnnotateAttr --- clang/include/clang/AST/Attr.h | 17 ++ clang/lib/Sema/SemaStmtAttr.cpp| 20 clang/lib/Sema/SemaTemplateInstantiate.cpp | 14 clang/test/AST/attr-print-emit.cpp | 3 ++ clang/test/Sema/annotate.c | 3 ++ clang/test/SemaTemplate/attributes.cpp | 38 ++ 6 files changed, 95 insertions(+) diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h index ac44e9fdd7c4e9..725498e132fc28 100644 --- a/clang/include/clang/AST/Attr.h +++ b/clang/include/clang/AST/Attr.h @@ -197,6 +197,23 @@ class InheritableParamAttr : public InheritableAttr { } }; +class InheritableParamOrStmtAttr : public InheritableParamAttr { +protected: + InheritableParamOrStmtAttr(ASTContext &Context, + const AttributeCommonInfo &CommonInfo, + attr::Kind AK, bool IsLateParsed, + bool InheritEvenIfAlreadyPresent) + : InheritableParamAttr(Context, CommonInfo, AK, IsLateParsed, + InheritEvenIfAlreadyPresent) {} + +public: + // Implement isa/cast/dyncast/etc. + static bool classof(const Attr *A) { +return A->getKind() >= attr::FirstInheritableParamOrStmtAttr && + A->getKind() <= attr::LastInheritableParamOrStmtAttr; + } +}; + class HLSLAnnotationAttr : public InheritableAttr { protected: HLSLAnnotationAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo, diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/c
[clang] [clang][frontend] Support applying the annotate attribute to statements (PR #111841)
https://github.com/ericastor closed https://github.com/llvm/llvm-project/pull/111841 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Instantiate attributes on other decl types (PR #115924)
@@ -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}} ericastor wrote: 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. https://github.com/llvm/llvm-project/pull/115924 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Instantiate attributes on other decl types (PR #115924)
ericastor wrote: > The change is reasonable, but I need to see tests for each of the types. > > In general, we've had the attitude of "we can enable this instantiation once > we see examples of it being useful", so we need tests to make sure it is > instantiated, AND that it is useful. This makes a lot of sense... but I'm not sure there's currently a way to write a FileCheck test for (e.g.) attributes on labels, which is actually my motivating case here. It'd be a pretty big change to start dumping label attributes in text AST dumps when the LabelDecl isn't even shown. Any suggestions? https://github.com/llvm/llvm-project/pull/115924 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Instantiate attributes on other decl types (PR #115924)
https://github.com/ericastor created https://github.com/llvm/llvm-project/pull/115924 Start propagating attributes on (e.g.) labels inside of templated functions to their instances. >From da2e66a6a2636bf1a1ab2e25afdbd29095b6db3f Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Tue, 12 Nov 2024 17:37:42 + Subject: [PATCH] [clang] Instantiate attributes on other decl types Start propagating attributes on (e.g.) labels inside of templated functions to their instances. --- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 16 +--- clang/test/SemaCXX/attr-mode-tmpl.cpp | 4 ++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 5a001843e2ba46..bfc5913dbafd0f 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -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; } @@ -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; } @@ -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; } @@ -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; } diff --git a/clang/test/SemaCXX/attr-mode-tmpl.cpp b/clang/test/SemaCXX/attr-mode-tmpl.cpp index f665b1ba491237..58266f947051c5 100644 --- a/clang/test/SemaCXX/attr-mode-tmpl.cpp +++ b/clang/test/SemaCXX/attr-mode-tmpl.cpp @@ -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}} // expected-warning@-1{{specifying vector types with the 'mode' attribute is deprecated}} typedef enum __attribute__((mode(HI))) { A4, B4 } T4; @@ -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. ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][frontend] Add support for attribute plugins for statement attributes (PR #110334)
https://github.com/ericastor created https://github.com/llvm/llvm-project/pull/110334 We already have support for declaration attributes; this is just a matter of extending the plugin infrastructure to cover one more case. >From 0411b2939e10ca335e84731502126145509bef2d Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Fri, 27 Sep 2024 22:35:28 + Subject: [PATCH] [clang][frontend] Add support for attribute plugins for statement attributes We already have support for declaration attributes; this is just a matter of extending the plugin infrastructure to cover one more case. --- clang/docs/ClangPlugins.rst| 17 +--- clang/examples/Attribute/Attribute.cpp | 49 ++ clang/include/clang/Basic/ParsedAttrInfo.h | 10 + clang/lib/Sema/SemaStmtAttr.cpp| 4 ++ clang/test/Frontend/plugin-attribute.cpp | 40 ++ 5 files changed, 108 insertions(+), 12 deletions(-) diff --git a/clang/docs/ClangPlugins.rst b/clang/docs/ClangPlugins.rst index 001e66e434efb1..92e41fb5877fe8 100644 --- a/clang/docs/ClangPlugins.rst +++ b/clang/docs/ClangPlugins.rst @@ -92,11 +92,6 @@ The members of ``ParsedAttrInfo`` that a plugin attribute must define are: attribute, each of which consists of an attribute syntax and how the attribute name is spelled for that syntax. If the syntax allows a scope then the spelling must be "scope::attr" if a scope is present or "::attr" if not. - * ``handleDeclAttribute``, which is the function that applies the attribute to - a declaration. It is responsible for checking that the attribute's arguments - are valid, and typically applies the attribute by adding an ``Attr`` to the - ``Decl``. It returns either ``AttributeApplied``, to indicate that the - attribute was successfully applied, or ``AttributeNotApplied`` if it wasn't. The members of ``ParsedAttrInfo`` that may need to be defined, depending on the attribute, are: @@ -105,6 +100,18 @@ attribute, are: arguments to the attribute. * ``diagAppertainsToDecl``, which checks if the attribute has been used on the right kind of declaration and issues a diagnostic if not. + * ``handleDeclAttribute``, which is the function that applies the attribute to + a declaration. It is responsible for checking that the attribute's arguments + are valid, and typically applies the attribute by adding an ``Attr`` to the + ``Decl``. It returns either ``AttributeApplied``, to indicate that the + attribute was successfully applied, or ``AttributeNotApplied`` if it wasn't. + * ``diagAppertainsToStmt``, which checks if the attribute has been used on the + right kind of statement and issues a diagnostic if not. + * ``handleStmtAttribute``, which is the function that applies the attribute to + a statement. It is responsible for checking that the attribute's arguments + are valid, and typically applies the attribute by adding an ``Attr`` to the + ``Stmt``. It returns either ``AttributeApplied``, to indicate that the + attribute was successfully applied, or ``AttributeNotApplied`` if it wasn't. * ``diagLangOpts``, which checks if the attribute is permitted for the current language mode and issues a diagnostic if not. * ``existsInTarget``, which checks if the attribute is permitted for the given diff --git a/clang/examples/Attribute/Attribute.cpp b/clang/examples/Attribute/Attribute.cpp index 9d6cf9ae36c6a6..07dd19321195c8 100644 --- a/clang/examples/Attribute/Attribute.cpp +++ b/clang/examples/Attribute/Attribute.cpp @@ -94,6 +94,55 @@ struct ExampleAttrInfo : public ParsedAttrInfo { } return AttributeApplied; } + + bool diagAppertainsToStmt(Sema &S, const ParsedAttr &Attr, +const Stmt *St) const override { +// This attribute appertains to for loop statements only. +if (!isa(St)) { + S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type_str) + << Attr << Attr.isRegularKeywordAttribute() << "for loop statements"; + return false; +} +return true; + } + + AttrHandling handleStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &Attr, + class Attr *&Result) const override { +// We make some rules here: +// 1. Only accept at most 3 arguments here. +// 2. The first argument must be a string literal if it exists. +if (Attr.getNumArgs() > 3) { + unsigned ID = S.getDiagnostics().getCustomDiagID( + DiagnosticsEngine::Error, + "'example' attribute only accepts at most three arguments"); + S.Diag(Attr.getLoc(), ID); + return AttributeNotApplied; +} +// If there are arguments, the first argument should be a string literal. +if (Attr.getNumArgs() > 0) { + auto *Arg0 = Attr.getArgAsExpr(0); + StringLiteral *Literal = + dyn_cast(Arg0->IgnoreParenCasts()); + if (!Literal) { +unsigned ID = S.getDiagnostics().getCustomDiagID( +DiagnosticsEng
[clang] [clang][frontend] Add support for attribute plugins for statement attributes (PR #110334)
https://github.com/ericastor updated https://github.com/llvm/llvm-project/pull/110334 >From 0411b2939e10ca335e84731502126145509bef2d Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Fri, 27 Sep 2024 22:35:28 + Subject: [PATCH] [clang][frontend] Add support for attribute plugins for statement attributes We already have support for declaration attributes; this is just a matter of extending the plugin infrastructure to cover one more case. --- clang/docs/ClangPlugins.rst| 17 +--- clang/examples/Attribute/Attribute.cpp | 49 ++ clang/include/clang/Basic/ParsedAttrInfo.h | 10 + clang/lib/Sema/SemaStmtAttr.cpp| 4 ++ clang/test/Frontend/plugin-attribute.cpp | 40 ++ 5 files changed, 108 insertions(+), 12 deletions(-) diff --git a/clang/docs/ClangPlugins.rst b/clang/docs/ClangPlugins.rst index 001e66e434efb1..92e41fb5877fe8 100644 --- a/clang/docs/ClangPlugins.rst +++ b/clang/docs/ClangPlugins.rst @@ -92,11 +92,6 @@ The members of ``ParsedAttrInfo`` that a plugin attribute must define are: attribute, each of which consists of an attribute syntax and how the attribute name is spelled for that syntax. If the syntax allows a scope then the spelling must be "scope::attr" if a scope is present or "::attr" if not. - * ``handleDeclAttribute``, which is the function that applies the attribute to - a declaration. It is responsible for checking that the attribute's arguments - are valid, and typically applies the attribute by adding an ``Attr`` to the - ``Decl``. It returns either ``AttributeApplied``, to indicate that the - attribute was successfully applied, or ``AttributeNotApplied`` if it wasn't. The members of ``ParsedAttrInfo`` that may need to be defined, depending on the attribute, are: @@ -105,6 +100,18 @@ attribute, are: arguments to the attribute. * ``diagAppertainsToDecl``, which checks if the attribute has been used on the right kind of declaration and issues a diagnostic if not. + * ``handleDeclAttribute``, which is the function that applies the attribute to + a declaration. It is responsible for checking that the attribute's arguments + are valid, and typically applies the attribute by adding an ``Attr`` to the + ``Decl``. It returns either ``AttributeApplied``, to indicate that the + attribute was successfully applied, or ``AttributeNotApplied`` if it wasn't. + * ``diagAppertainsToStmt``, which checks if the attribute has been used on the + right kind of statement and issues a diagnostic if not. + * ``handleStmtAttribute``, which is the function that applies the attribute to + a statement. It is responsible for checking that the attribute's arguments + are valid, and typically applies the attribute by adding an ``Attr`` to the + ``Stmt``. It returns either ``AttributeApplied``, to indicate that the + attribute was successfully applied, or ``AttributeNotApplied`` if it wasn't. * ``diagLangOpts``, which checks if the attribute is permitted for the current language mode and issues a diagnostic if not. * ``existsInTarget``, which checks if the attribute is permitted for the given diff --git a/clang/examples/Attribute/Attribute.cpp b/clang/examples/Attribute/Attribute.cpp index 9d6cf9ae36c6a6..07dd19321195c8 100644 --- a/clang/examples/Attribute/Attribute.cpp +++ b/clang/examples/Attribute/Attribute.cpp @@ -94,6 +94,55 @@ struct ExampleAttrInfo : public ParsedAttrInfo { } return AttributeApplied; } + + bool diagAppertainsToStmt(Sema &S, const ParsedAttr &Attr, +const Stmt *St) const override { +// This attribute appertains to for loop statements only. +if (!isa(St)) { + S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type_str) + << Attr << Attr.isRegularKeywordAttribute() << "for loop statements"; + return false; +} +return true; + } + + AttrHandling handleStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &Attr, + class Attr *&Result) const override { +// We make some rules here: +// 1. Only accept at most 3 arguments here. +// 2. The first argument must be a string literal if it exists. +if (Attr.getNumArgs() > 3) { + unsigned ID = S.getDiagnostics().getCustomDiagID( + DiagnosticsEngine::Error, + "'example' attribute only accepts at most three arguments"); + S.Diag(Attr.getLoc(), ID); + return AttributeNotApplied; +} +// If there are arguments, the first argument should be a string literal. +if (Attr.getNumArgs() > 0) { + auto *Arg0 = Attr.getArgAsExpr(0); + StringLiteral *Literal = + dyn_cast(Arg0->IgnoreParenCasts()); + if (!Literal) { +unsigned ID = S.getDiagnostics().getCustomDiagID( +DiagnosticsEngine::Error, "first argument to the 'example' " + "attribute must be a string literal"); +S.Dia
[clang] [clang][frontend] Add support for attribute plugins for statement attributes (PR #110334)
https://github.com/ericastor updated https://github.com/llvm/llvm-project/pull/110334 >From 0411b2939e10ca335e84731502126145509bef2d Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Fri, 27 Sep 2024 22:35:28 + Subject: [PATCH 1/2] [clang][frontend] Add support for attribute plugins for statement attributes We already have support for declaration attributes; this is just a matter of extending the plugin infrastructure to cover one more case. --- clang/docs/ClangPlugins.rst| 17 +--- clang/examples/Attribute/Attribute.cpp | 49 ++ clang/include/clang/Basic/ParsedAttrInfo.h | 10 + clang/lib/Sema/SemaStmtAttr.cpp| 4 ++ clang/test/Frontend/plugin-attribute.cpp | 40 ++ 5 files changed, 108 insertions(+), 12 deletions(-) diff --git a/clang/docs/ClangPlugins.rst b/clang/docs/ClangPlugins.rst index 001e66e434efb1..92e41fb5877fe8 100644 --- a/clang/docs/ClangPlugins.rst +++ b/clang/docs/ClangPlugins.rst @@ -92,11 +92,6 @@ The members of ``ParsedAttrInfo`` that a plugin attribute must define are: attribute, each of which consists of an attribute syntax and how the attribute name is spelled for that syntax. If the syntax allows a scope then the spelling must be "scope::attr" if a scope is present or "::attr" if not. - * ``handleDeclAttribute``, which is the function that applies the attribute to - a declaration. It is responsible for checking that the attribute's arguments - are valid, and typically applies the attribute by adding an ``Attr`` to the - ``Decl``. It returns either ``AttributeApplied``, to indicate that the - attribute was successfully applied, or ``AttributeNotApplied`` if it wasn't. The members of ``ParsedAttrInfo`` that may need to be defined, depending on the attribute, are: @@ -105,6 +100,18 @@ attribute, are: arguments to the attribute. * ``diagAppertainsToDecl``, which checks if the attribute has been used on the right kind of declaration and issues a diagnostic if not. + * ``handleDeclAttribute``, which is the function that applies the attribute to + a declaration. It is responsible for checking that the attribute's arguments + are valid, and typically applies the attribute by adding an ``Attr`` to the + ``Decl``. It returns either ``AttributeApplied``, to indicate that the + attribute was successfully applied, or ``AttributeNotApplied`` if it wasn't. + * ``diagAppertainsToStmt``, which checks if the attribute has been used on the + right kind of statement and issues a diagnostic if not. + * ``handleStmtAttribute``, which is the function that applies the attribute to + a statement. It is responsible for checking that the attribute's arguments + are valid, and typically applies the attribute by adding an ``Attr`` to the + ``Stmt``. It returns either ``AttributeApplied``, to indicate that the + attribute was successfully applied, or ``AttributeNotApplied`` if it wasn't. * ``diagLangOpts``, which checks if the attribute is permitted for the current language mode and issues a diagnostic if not. * ``existsInTarget``, which checks if the attribute is permitted for the given diff --git a/clang/examples/Attribute/Attribute.cpp b/clang/examples/Attribute/Attribute.cpp index 9d6cf9ae36c6a6..07dd19321195c8 100644 --- a/clang/examples/Attribute/Attribute.cpp +++ b/clang/examples/Attribute/Attribute.cpp @@ -94,6 +94,55 @@ struct ExampleAttrInfo : public ParsedAttrInfo { } return AttributeApplied; } + + bool diagAppertainsToStmt(Sema &S, const ParsedAttr &Attr, +const Stmt *St) const override { +// This attribute appertains to for loop statements only. +if (!isa(St)) { + S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type_str) + << Attr << Attr.isRegularKeywordAttribute() << "for loop statements"; + return false; +} +return true; + } + + AttrHandling handleStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &Attr, + class Attr *&Result) const override { +// We make some rules here: +// 1. Only accept at most 3 arguments here. +// 2. The first argument must be a string literal if it exists. +if (Attr.getNumArgs() > 3) { + unsigned ID = S.getDiagnostics().getCustomDiagID( + DiagnosticsEngine::Error, + "'example' attribute only accepts at most three arguments"); + S.Diag(Attr.getLoc(), ID); + return AttributeNotApplied; +} +// If there are arguments, the first argument should be a string literal. +if (Attr.getNumArgs() > 0) { + auto *Arg0 = Attr.getArgAsExpr(0); + StringLiteral *Literal = + dyn_cast(Arg0->IgnoreParenCasts()); + if (!Literal) { +unsigned ID = S.getDiagnostics().getCustomDiagID( +DiagnosticsEngine::Error, "first argument to the 'example' " + "attribute must be a string literal"); +S
[clang] [clang][frontend] Add support for attribute plugins for statement attributes (PR #110334)
ericastor wrote: > So the problem with statement attributes is that we don't really have a good > way to do instantiation of them on a template, which is why we held off on > this in the first place. The infrastructure for instantiation DOES happen on > decl attributes automatically anyway, so that made it easier to do. > > So please ensure there is some sort of hooks in the statement attributes to > ensure that they get a chance to instantatiate themselves (and add tests with > templates in them!). This is a fair point... how are standard statement attributes handled inside of templates? (Assuming clang supports that.) https://github.com/llvm/llvm-project/pull/110334 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Instantiate attributes on LabelDecls (PR #115924)
https://github.com/ericastor updated https://github.com/llvm/llvm-project/pull/115924 >From da2e66a6a2636bf1a1ab2e25afdbd29095b6db3f Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Tue, 12 Nov 2024 17:37:42 + Subject: [PATCH 1/6] [clang] Instantiate attributes on other decl types Start propagating attributes on (e.g.) labels inside of templated functions to their instances. --- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 16 +--- clang/test/SemaCXX/attr-mode-tmpl.cpp | 4 ++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 5a001843e2ba46..bfc5913dbafd0f 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -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; } @@ -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; } @@ -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; } @@ -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; } diff --git a/clang/test/SemaCXX/attr-mode-tmpl.cpp b/clang/test/SemaCXX/attr-mode-tmpl.cpp index f665b1ba491237..58266f947051c5 100644 --- a/clang/test/SemaCXX/attr-mode-tmpl.cpp +++ b/clang/test/SemaCXX/attr-mode-tmpl.cpp @@ -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}} // expected-warning@-1{{specifying vector types with the 'mode' attribute is deprecated}} typedef enum __attribute__((mode(HI))) { A4, B4 } T4; @@ -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. >From eb4b3a2d1e25b9fc63048e5f2d71d62a3cbd2bde Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Thu, 14 Nov 2024 19:24:45 + Subject: [PATCH 2/6] Include attributes on LabelStmts (forwarding from decls) in AST dumps We apply this to add a test of the new label attribute instantiation support. --- clang/examples/Attribute/Attribute.cpp | 6 +++--- clang/include/clang/AST/ASTNodeTraverser.h | 5 + clang/test/Frontend/plugin-attribute.cpp | 8 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/clang/examples/Attribute/Attribute.cpp b/clang/examples/Attribute/Attribute.cpp index 3b90724ad22205..59446a15a6925d 100644 --- a/clang/examples/Attribute/Attribute.cpp +++ b/clang/examples/Attribute/Attribute.cpp @@ -41,9 +41,9 @@ struct ExampleAttrInfo : public ParsedAttrInfo { bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr, const Decl *D) const override { // This
[clang] [clang] Instantiate attributes on LabelDecls (PR #115924)
https://github.com/ericastor updated https://github.com/llvm/llvm-project/pull/115924 >From da2e66a6a2636bf1a1ab2e25afdbd29095b6db3f Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Tue, 12 Nov 2024 17:37:42 + Subject: [PATCH 1/8] [clang] Instantiate attributes on other decl types Start propagating attributes on (e.g.) labels inside of templated functions to their instances. --- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 16 +--- clang/test/SemaCXX/attr-mode-tmpl.cpp | 4 ++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 5a001843e2ba46..bfc5913dbafd0f 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -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; } @@ -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; } @@ -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; } @@ -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; } diff --git a/clang/test/SemaCXX/attr-mode-tmpl.cpp b/clang/test/SemaCXX/attr-mode-tmpl.cpp index f665b1ba491237..58266f947051c5 100644 --- a/clang/test/SemaCXX/attr-mode-tmpl.cpp +++ b/clang/test/SemaCXX/attr-mode-tmpl.cpp @@ -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}} // expected-warning@-1{{specifying vector types with the 'mode' attribute is deprecated}} typedef enum __attribute__((mode(HI))) { A4, B4 } T4; @@ -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. >From eb4b3a2d1e25b9fc63048e5f2d71d62a3cbd2bde Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Thu, 14 Nov 2024 19:24:45 + Subject: [PATCH 2/8] Include attributes on LabelStmts (forwarding from decls) in AST dumps We apply this to add a test of the new label attribute instantiation support. --- clang/examples/Attribute/Attribute.cpp | 6 +++--- clang/include/clang/AST/ASTNodeTraverser.h | 5 + clang/test/Frontend/plugin-attribute.cpp | 8 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/clang/examples/Attribute/Attribute.cpp b/clang/examples/Attribute/Attribute.cpp index 3b90724ad22205..59446a15a6925d 100644 --- a/clang/examples/Attribute/Attribute.cpp +++ b/clang/examples/Attribute/Attribute.cpp @@ -41,9 +41,9 @@ struct ExampleAttrInfo : public ParsedAttrInfo { bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr, const Decl *D) const override { // This
[clang] [clang] Instantiate attributes on LabelDecls (PR #115924)
ericastor wrote: > Test seems to have disappeared entirely! Whoops. Apologies, missed that I'd forgotten to track the new file. https://github.com/llvm/llvm-project/pull/115924 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Instantiate attributes on LabelDecls (PR #115924)
https://github.com/ericastor updated https://github.com/llvm/llvm-project/pull/115924 >From da2e66a6a2636bf1a1ab2e25afdbd29095b6db3f Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Tue, 12 Nov 2024 17:37:42 + Subject: [PATCH 1/8] [clang] Instantiate attributes on other decl types Start propagating attributes on (e.g.) labels inside of templated functions to their instances. --- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 16 +--- clang/test/SemaCXX/attr-mode-tmpl.cpp | 4 ++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 5a001843e2ba46..bfc5913dbafd0f 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -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; } @@ -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; } @@ -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; } @@ -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; } diff --git a/clang/test/SemaCXX/attr-mode-tmpl.cpp b/clang/test/SemaCXX/attr-mode-tmpl.cpp index f665b1ba491237..58266f947051c5 100644 --- a/clang/test/SemaCXX/attr-mode-tmpl.cpp +++ b/clang/test/SemaCXX/attr-mode-tmpl.cpp @@ -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}} // expected-warning@-1{{specifying vector types with the 'mode' attribute is deprecated}} typedef enum __attribute__((mode(HI))) { A4, B4 } T4; @@ -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. >From eb4b3a2d1e25b9fc63048e5f2d71d62a3cbd2bde Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Thu, 14 Nov 2024 19:24:45 + Subject: [PATCH 2/8] Include attributes on LabelStmts (forwarding from decls) in AST dumps We apply this to add a test of the new label attribute instantiation support. --- clang/examples/Attribute/Attribute.cpp | 6 +++--- clang/include/clang/AST/ASTNodeTraverser.h | 5 + clang/test/Frontend/plugin-attribute.cpp | 8 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/clang/examples/Attribute/Attribute.cpp b/clang/examples/Attribute/Attribute.cpp index 3b90724ad22205..59446a15a6925d 100644 --- a/clang/examples/Attribute/Attribute.cpp +++ b/clang/examples/Attribute/Attribute.cpp @@ -41,9 +41,9 @@ struct ExampleAttrInfo : public ParsedAttrInfo { bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr, const Decl *D) const override { // This
[clang] [clang] Instantiate attributes on LabelDecls (PR #115924)
https://github.com/ericastor updated https://github.com/llvm/llvm-project/pull/115924 >From da2e66a6a2636bf1a1ab2e25afdbd29095b6db3f Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Tue, 12 Nov 2024 17:37:42 + Subject: [PATCH 1/7] [clang] Instantiate attributes on other decl types Start propagating attributes on (e.g.) labels inside of templated functions to their instances. --- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 16 +--- clang/test/SemaCXX/attr-mode-tmpl.cpp | 4 ++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 5a001843e2ba46..bfc5913dbafd0f 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -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; } @@ -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; } @@ -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; } @@ -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; } diff --git a/clang/test/SemaCXX/attr-mode-tmpl.cpp b/clang/test/SemaCXX/attr-mode-tmpl.cpp index f665b1ba491237..58266f947051c5 100644 --- a/clang/test/SemaCXX/attr-mode-tmpl.cpp +++ b/clang/test/SemaCXX/attr-mode-tmpl.cpp @@ -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}} // expected-warning@-1{{specifying vector types with the 'mode' attribute is deprecated}} typedef enum __attribute__((mode(HI))) { A4, B4 } T4; @@ -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. >From eb4b3a2d1e25b9fc63048e5f2d71d62a3cbd2bde Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Thu, 14 Nov 2024 19:24:45 + Subject: [PATCH 2/7] Include attributes on LabelStmts (forwarding from decls) in AST dumps We apply this to add a test of the new label attribute instantiation support. --- clang/examples/Attribute/Attribute.cpp | 6 +++--- clang/include/clang/AST/ASTNodeTraverser.h | 5 + clang/test/Frontend/plugin-attribute.cpp | 8 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/clang/examples/Attribute/Attribute.cpp b/clang/examples/Attribute/Attribute.cpp index 3b90724ad22205..59446a15a6925d 100644 --- a/clang/examples/Attribute/Attribute.cpp +++ b/clang/examples/Attribute/Attribute.cpp @@ -41,9 +41,9 @@ struct ExampleAttrInfo : public ParsedAttrInfo { bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr, const Decl *D) const override { // This
[clang] [clang] Instantiate attributes on LabelDecls (PR #115924)
https://github.com/ericastor updated https://github.com/llvm/llvm-project/pull/115924 >From da2e66a6a2636bf1a1ab2e25afdbd29095b6db3f Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Tue, 12 Nov 2024 17:37:42 + Subject: [PATCH 1/7] [clang] Instantiate attributes on other decl types Start propagating attributes on (e.g.) labels inside of templated functions to their instances. --- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 16 +--- clang/test/SemaCXX/attr-mode-tmpl.cpp | 4 ++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 5a001843e2ba46..bfc5913dbafd0f 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -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; } @@ -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; } @@ -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; } @@ -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; } diff --git a/clang/test/SemaCXX/attr-mode-tmpl.cpp b/clang/test/SemaCXX/attr-mode-tmpl.cpp index f665b1ba491237..58266f947051c5 100644 --- a/clang/test/SemaCXX/attr-mode-tmpl.cpp +++ b/clang/test/SemaCXX/attr-mode-tmpl.cpp @@ -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}} // expected-warning@-1{{specifying vector types with the 'mode' attribute is deprecated}} typedef enum __attribute__((mode(HI))) { A4, B4 } T4; @@ -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. >From eb4b3a2d1e25b9fc63048e5f2d71d62a3cbd2bde Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Thu, 14 Nov 2024 19:24:45 + Subject: [PATCH 2/7] Include attributes on LabelStmts (forwarding from decls) in AST dumps We apply this to add a test of the new label attribute instantiation support. --- clang/examples/Attribute/Attribute.cpp | 6 +++--- clang/include/clang/AST/ASTNodeTraverser.h | 5 + clang/test/Frontend/plugin-attribute.cpp | 8 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/clang/examples/Attribute/Attribute.cpp b/clang/examples/Attribute/Attribute.cpp index 3b90724ad22205..59446a15a6925d 100644 --- a/clang/examples/Attribute/Attribute.cpp +++ b/clang/examples/Attribute/Attribute.cpp @@ -41,9 +41,9 @@ struct ExampleAttrInfo : public ParsedAttrInfo { bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr, const Decl *D) const override { // This
[clang] [clang] Instantiate attributes on LabelDecls (PR #115924)
ericastor wrote: > test needs some simplification/help, else this is fine. Thanks, I was mimicking another file that apparently isn't following best practices. Done! https://github.com/llvm/llvm-project/pull/115924 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Instantiate attributes on other decl types (PR #115924)
https://github.com/ericastor updated https://github.com/llvm/llvm-project/pull/115924 >From da2e66a6a2636bf1a1ab2e25afdbd29095b6db3f Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Tue, 12 Nov 2024 17:37:42 + Subject: [PATCH 1/3] [clang] Instantiate attributes on other decl types Start propagating attributes on (e.g.) labels inside of templated functions to their instances. --- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 16 +--- clang/test/SemaCXX/attr-mode-tmpl.cpp | 4 ++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 5a001843e2ba46..bfc5913dbafd0f 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -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; } @@ -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; } @@ -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; } @@ -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; } diff --git a/clang/test/SemaCXX/attr-mode-tmpl.cpp b/clang/test/SemaCXX/attr-mode-tmpl.cpp index f665b1ba491237..58266f947051c5 100644 --- a/clang/test/SemaCXX/attr-mode-tmpl.cpp +++ b/clang/test/SemaCXX/attr-mode-tmpl.cpp @@ -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}} // expected-warning@-1{{specifying vector types with the 'mode' attribute is deprecated}} typedef enum __attribute__((mode(HI))) { A4, B4 } T4; @@ -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. >From eb4b3a2d1e25b9fc63048e5f2d71d62a3cbd2bde Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Thu, 14 Nov 2024 19:24:45 + Subject: [PATCH 2/3] Include attributes on LabelStmts (forwarding from decls) in AST dumps We apply this to add a test of the new label attribute instantiation support. --- clang/examples/Attribute/Attribute.cpp | 6 +++--- clang/include/clang/AST/ASTNodeTraverser.h | 5 + clang/test/Frontend/plugin-attribute.cpp | 8 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/clang/examples/Attribute/Attribute.cpp b/clang/examples/Attribute/Attribute.cpp index 3b90724ad22205..59446a15a6925d 100644 --- a/clang/examples/Attribute/Attribute.cpp +++ b/clang/examples/Attribute/Attribute.cpp @@ -41,9 +41,9 @@ struct ExampleAttrInfo : public ParsedAttrInfo { bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr, const Decl *D) const override { // This
[clang] [clang] Instantiate attributes on other decl types (PR #115924)
ericastor wrote: > Still need tests for namespacealiasdecl, typedefnamedecl, and > typealiastemplatedecl actually being instantiated. > > Also, is there a reason why the only way to currently test these are with the > plugins? I would expect there to be SOME builtin attribute that could be > validated for all of those as well. Since I'm not fully familiar with all of the attributes that could be applied to those decls, I'm withdrawing those parts of this PR for now. I'll be happy to help with those separately. I'll look into whether I can test it without using plugins, but I first wanted to get *any* test working with LabelDecl, and (as mentioned) I wasn't sure what built-in attributes would apply. I'll follow up with more tests. https://github.com/llvm/llvm-project/pull/115924 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Instantiate attributes on other decl types (PR #115924)
https://github.com/ericastor updated https://github.com/llvm/llvm-project/pull/115924 >From da2e66a6a2636bf1a1ab2e25afdbd29095b6db3f Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Tue, 12 Nov 2024 17:37:42 + Subject: [PATCH 1/2] [clang] Instantiate attributes on other decl types Start propagating attributes on (e.g.) labels inside of templated functions to their instances. --- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 16 +--- clang/test/SemaCXX/attr-mode-tmpl.cpp | 4 ++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 5a001843e2ba46..bfc5913dbafd0f 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -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; } @@ -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; } @@ -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; } @@ -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; } diff --git a/clang/test/SemaCXX/attr-mode-tmpl.cpp b/clang/test/SemaCXX/attr-mode-tmpl.cpp index f665b1ba491237..58266f947051c5 100644 --- a/clang/test/SemaCXX/attr-mode-tmpl.cpp +++ b/clang/test/SemaCXX/attr-mode-tmpl.cpp @@ -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}} // expected-warning@-1{{specifying vector types with the 'mode' attribute is deprecated}} typedef enum __attribute__((mode(HI))) { A4, B4 } T4; @@ -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. >From eb4b3a2d1e25b9fc63048e5f2d71d62a3cbd2bde Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Thu, 14 Nov 2024 19:24:45 + Subject: [PATCH 2/2] Include attributes on LabelStmts (forwarding from decls) in AST dumps We apply this to add a test of the new label attribute instantiation support. --- clang/examples/Attribute/Attribute.cpp | 6 +++--- clang/include/clang/AST/ASTNodeTraverser.h | 5 + clang/test/Frontend/plugin-attribute.cpp | 8 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/clang/examples/Attribute/Attribute.cpp b/clang/examples/Attribute/Attribute.cpp index 3b90724ad22205..59446a15a6925d 100644 --- a/clang/examples/Attribute/Attribute.cpp +++ b/clang/examples/Attribute/Attribute.cpp @@ -41,9 +41,9 @@ struct ExampleAttrInfo : public ParsedAttrInfo { bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr, const Decl *D) const override { // This
[clang] [clang] Instantiate attributes on LabelDecls (PR #115924)
ericastor wrote: Alright, I've scoped this change back down to just LabelDecls, and added tests that avoid the use of plugins. I appreciate your review! https://github.com/llvm/llvm-project/pull/115924 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Instantiate attributes on LabelDecls (PR #115924)
https://github.com/ericastor edited https://github.com/llvm/llvm-project/pull/115924 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Instantiate attributes on other decl types (PR #115924)
https://github.com/ericastor updated https://github.com/llvm/llvm-project/pull/115924 >From da2e66a6a2636bf1a1ab2e25afdbd29095b6db3f Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Tue, 12 Nov 2024 17:37:42 + Subject: [PATCH 1/3] [clang] Instantiate attributes on other decl types Start propagating attributes on (e.g.) labels inside of templated functions to their instances. --- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 16 +--- clang/test/SemaCXX/attr-mode-tmpl.cpp | 4 ++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 5a001843e2ba46..bfc5913dbafd0f 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -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; } @@ -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; } @@ -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; } @@ -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; } diff --git a/clang/test/SemaCXX/attr-mode-tmpl.cpp b/clang/test/SemaCXX/attr-mode-tmpl.cpp index f665b1ba491237..58266f947051c5 100644 --- a/clang/test/SemaCXX/attr-mode-tmpl.cpp +++ b/clang/test/SemaCXX/attr-mode-tmpl.cpp @@ -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}} // expected-warning@-1{{specifying vector types with the 'mode' attribute is deprecated}} typedef enum __attribute__((mode(HI))) { A4, B4 } T4; @@ -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. >From eb4b3a2d1e25b9fc63048e5f2d71d62a3cbd2bde Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Thu, 14 Nov 2024 19:24:45 + Subject: [PATCH 2/3] Include attributes on LabelStmts (forwarding from decls) in AST dumps We apply this to add a test of the new label attribute instantiation support. --- clang/examples/Attribute/Attribute.cpp | 6 +++--- clang/include/clang/AST/ASTNodeTraverser.h | 5 + clang/test/Frontend/plugin-attribute.cpp | 8 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/clang/examples/Attribute/Attribute.cpp b/clang/examples/Attribute/Attribute.cpp index 3b90724ad22205..59446a15a6925d 100644 --- a/clang/examples/Attribute/Attribute.cpp +++ b/clang/examples/Attribute/Attribute.cpp @@ -41,9 +41,9 @@ struct ExampleAttrInfo : public ParsedAttrInfo { bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr, const Decl *D) const override { // This
[clang] [clang] Instantiate attributes on other decl types (PR #115924)
https://github.com/ericastor updated https://github.com/llvm/llvm-project/pull/115924 >From da2e66a6a2636bf1a1ab2e25afdbd29095b6db3f Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Tue, 12 Nov 2024 17:37:42 + Subject: [PATCH 1/5] [clang] Instantiate attributes on other decl types Start propagating attributes on (e.g.) labels inside of templated functions to their instances. --- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 16 +--- clang/test/SemaCXX/attr-mode-tmpl.cpp | 4 ++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 5a001843e2ba46..bfc5913dbafd0f 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -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; } @@ -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; } @@ -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; } @@ -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; } diff --git a/clang/test/SemaCXX/attr-mode-tmpl.cpp b/clang/test/SemaCXX/attr-mode-tmpl.cpp index f665b1ba491237..58266f947051c5 100644 --- a/clang/test/SemaCXX/attr-mode-tmpl.cpp +++ b/clang/test/SemaCXX/attr-mode-tmpl.cpp @@ -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}} // expected-warning@-1{{specifying vector types with the 'mode' attribute is deprecated}} typedef enum __attribute__((mode(HI))) { A4, B4 } T4; @@ -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. >From eb4b3a2d1e25b9fc63048e5f2d71d62a3cbd2bde Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Thu, 14 Nov 2024 19:24:45 + Subject: [PATCH 2/5] Include attributes on LabelStmts (forwarding from decls) in AST dumps We apply this to add a test of the new label attribute instantiation support. --- clang/examples/Attribute/Attribute.cpp | 6 +++--- clang/include/clang/AST/ASTNodeTraverser.h | 5 + clang/test/Frontend/plugin-attribute.cpp | 8 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/clang/examples/Attribute/Attribute.cpp b/clang/examples/Attribute/Attribute.cpp index 3b90724ad22205..59446a15a6925d 100644 --- a/clang/examples/Attribute/Attribute.cpp +++ b/clang/examples/Attribute/Attribute.cpp @@ -41,9 +41,9 @@ struct ExampleAttrInfo : public ParsedAttrInfo { bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr, const Decl *D) const override { // This
[clang] [clang] Instantiate attributes on other decl types (PR #115924)
@@ -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(D)) { ericastor wrote: Moot; I've removed the plugin-based testing. https://github.com/llvm/llvm-project/pull/115924 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Instantiate attributes on LabelDecls (PR #115924)
https://github.com/ericastor closed https://github.com/llvm/llvm-project/pull/115924 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits