Skip to content

Commit 125bdd1

Browse files
committed
Handle dependent arguments
1 parent 2e07a17 commit 125bdd1

File tree

7 files changed

+98
-11
lines changed

7 files changed

+98
-11
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1979,7 +1979,7 @@ def Flatten : InheritableAttr {
19791979
def FlattenDepth : InheritableAttr {
19801980
let Spellings = [Clang<"flatten_depth">];
19811981
let Subjects = SubjectList<[Function], ErrorDiag>;
1982-
let Args = [UnsignedArgument<"DepthHint">];
1982+
let Args = [ExprArgument<"DepthHint">];
19831983
let Documentation = [FlattenDepthDocs];
19841984
}
19851985

clang/include/clang/Sema/Sema.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4905,6 +4905,10 @@ class Sema final : public SemaBase {
49054905
void AddAllocAlignAttr(Decl *D, const AttributeCommonInfo &CI,
49064906
Expr *ParamExpr);
49074907

4908+
/// addFlattenDepthAttr - Adds a flatten_depth attribute to a particular
4909+
/// declaration.
4910+
void addFlattenDepthAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E);
4911+
49084912
bool CheckAttrTarget(const ParsedAttr &CurrAttr);
49094913
bool CheckAttrNoArgs(const ParsedAttr &CurrAttr);
49104914

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2753,9 +2753,11 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
27532753

27542754
// Handle flatten_depth attribute for depth-based inlining
27552755
if (const FlattenDepthAttr *FDA = D->getAttr<FlattenDepthAttr>()) {
2756-
// Add the flatten_depth attribute with the max depth value as a typed int
2757-
// attribute
2758-
B.addFlattenDepthAttr(FDA->getDepthHint());
2756+
Expr *DepthExpr = FDA->getDepthHint();
2757+
Expr::EvalResult Result;
2758+
if (DepthExpr->EvaluateAsInt(Result, getContext())) {
2759+
B.addFlattenDepthAttr(Result.Val.getInt().getZExtValue());
2760+
}
27592761
}
27602762

27612763
// Track whether we need to add the optnone LLVM attribute,

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3695,20 +3695,28 @@ static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
36953695
D->addAttr(::new (S.Context) InitPriorityAttr(S.Context, AL, prioritynum));
36963696
}
36973697

3698-
static void handleFlattenDepthAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3699-
Expr *E = AL.getArgAsExpr(0);
3698+
void Sema::addFlattenDepthAttr(Decl *D, const AttributeCommonInfo &CI,
3699+
Expr *E) {
3700+
// If the expression is template-dependent, defer evaluation until
3701+
// instantiation
3702+
if (E->isValueDependent()) {
3703+
D->addAttr(FlattenDepthAttr::Create(Context, E, CI));
3704+
return;
3705+
}
3706+
3707+
// For non-dependent expressions, evaluate immediately
37003708
uint32_t depthHint;
3701-
if (!S.checkUInt32Argument(AL, E, depthHint)) {
3709+
if (!checkUInt32Argument(CI, E, depthHint)) {
37023710
return;
37033711
}
37043712

37053713
if (depthHint == 0) {
3706-
S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero)
3707-
<< AL << E->getSourceRange();
3714+
Diag(CI.getLoc(), diag::err_attribute_argument_is_zero)
3715+
<< CI << E->getSourceRange();
37083716
return;
37093717
}
37103718

3711-
D->addAttr(FlattenDepthAttr::Create(S.Context, depthHint, AL));
3719+
D->addAttr(FlattenDepthAttr::Create(Context, E, CI));
37123720
}
37133721

37143722
ErrorAttr *Sema::mergeErrorAttr(Decl *D, const AttributeCommonInfo &CI,
@@ -7253,7 +7261,7 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
72537261
handleFormatAttr(S, D, AL);
72547262
break;
72557263
case ParsedAttr::AT_FlattenDepth:
7256-
handleFlattenDepthAttr(S, D, AL);
7264+
S.addFlattenDepthAttr(D, AL, AL.getArgAsExpr(0));
72577265
break;
72587266
case ParsedAttr::AT_FormatMatches:
72597267
handleFormatMatchesAttr(S, D, AL);

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,21 @@ static void instantiateDependentAnnotationAttr(
234234
}
235235
}
236236

237+
static void instantiateDependentFlattenDepthAttr(
238+
Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
239+
const FlattenDepthAttr *Attr, Decl *New) {
240+
// The depth expression is a constant expression.
241+
EnterExpressionEvaluationContext Unevaluated(
242+
S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
243+
244+
ExprResult Result = S.SubstExpr(Attr->getDepthHint(), TemplateArgs);
245+
if (Result.isInvalid())
246+
return;
247+
248+
Expr *E = Result.getAs<Expr>();
249+
S.addFlattenDepthAttr(New, *Attr, E);
250+
}
251+
237252
template <typename Attr>
238253
static void sharedInstantiateConstructorDestructorAttr(
239254
Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, const Attr *A,
@@ -912,6 +927,12 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
912927
continue;
913928
}
914929

930+
if (const auto *FlattenDepth = dyn_cast<FlattenDepthAttr>(TmplAttr)) {
931+
instantiateDependentFlattenDepthAttr(*this, TemplateArgs, FlattenDepth,
932+
New);
933+
continue;
934+
}
935+
915936
if (const auto *OMPAttr = dyn_cast<OMPDeclareSimdDeclAttr>(TmplAttr)) {
916937
instantiateOMPDeclareSimdDeclAttr(*this, TemplateArgs, *OMPAttr, New);
917938
continue;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
2+
3+
template<typename T, unsigned I> struct S {
4+
5+
__attribute__((flatten_depth(I)))
6+
void func1(){/*...*/}
7+
8+
__attribute__((flatten_depth(T::value)))
9+
void func2(){/*...*/}
10+
11+
};
12+
13+
struct HasVal { static constexpr int value = 3; };
14+
15+
void foo() {
16+
S<HasVal, 2> s;
17+
s.func1();
18+
s.func2();
19+
}
20+
21+
// Verify the attribute values are correct
22+
// CHECK-DAG: flatten_depth=2
23+
// CHECK-DAG: flatten_depth=3
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %clang_cc1 -fsyntax-only -verify %s
2+
3+
template<typename T>
4+
struct S {
5+
__attribute__((flatten_depth(T::value)))
6+
void func() {}
7+
};
8+
9+
struct HasFloat {
10+
static constexpr float value = 3.14f;
11+
};
12+
13+
struct HasPointer {
14+
static constexpr int* value = nullptr;
15+
};
16+
17+
struct HasString {
18+
static constexpr const char* value = "bad";
19+
};
20+
21+
void test() {
22+
S<HasFloat> s1; // expected-note {{in instantiation of template class 'S<HasFloat>' requested here}}
23+
S<HasPointer> s2; // expected-note {{in instantiation of template class 'S<HasPointer>' requested here}}
24+
S<HasString> s3; // expected-note {{in instantiation of template class 'S<HasString>' requested here}}
25+
}
26+
27+
// expected-error@5 {{'flatten_depth' attribute requires an integer constant}}
28+
// expected-error@5 {{'flatten_depth' attribute requires an integer constant}}
29+
// expected-error@5 {{'flatten_depth' attribute requires an integer constant}}

0 commit comments

Comments
 (0)