|
22 | 22 | #include "clang/AST/DeclTemplate.h"
|
23 | 23 | #include "clang/AST/DeclarationName.h"
|
24 | 24 | #include "clang/AST/Expr.h"
|
25 |
| -#include "clang/AST/ExprConcepts.h" |
26 | 25 | #include "clang/AST/ExprCXX.h"
|
| 26 | +#include "clang/AST/ExprConcepts.h" |
27 | 27 | #include "clang/AST/ExprObjC.h"
|
28 | 28 | #include "clang/AST/ExternalASTSource.h"
|
29 | 29 | #include "clang/AST/LocInfoType.h"
|
|
34 | 34 | #include "clang/AST/TypeLoc.h"
|
35 | 35 | #include "clang/AST/TypeOrdering.h"
|
36 | 36 | #include "clang/Basic/BitmaskEnum.h"
|
| 37 | +#include "clang/Basic/DiagnosticSema.h" |
37 | 38 | #include "clang/Basic/ExpressionTraits.h"
|
38 | 39 | #include "clang/Basic/Module.h"
|
39 | 40 | #include "clang/Basic/OpenMPKinds.h"
|
@@ -12326,6 +12327,71 @@ class Sema final {
|
12326 | 12327 | void checkSYCLDeviceFunction(SourceLocation Loc, FunctionDecl *Callee);
|
12327 | 12328 | };
|
12328 | 12329 |
|
| 12330 | +template <typename AttrType> |
| 12331 | +void Sema::AddOneConstantValueAttr(Decl *D, const AttributeCommonInfo &CI, |
| 12332 | + Expr *E) { |
| 12333 | + AttrType TmpAttr(Context, CI, E); |
| 12334 | + |
| 12335 | + if (!E->isValueDependent()) { |
| 12336 | + ExprResult ICE; |
| 12337 | + if (checkRangedIntegralArgument<AttrType>(E, &TmpAttr, ICE)) |
| 12338 | + return; |
| 12339 | + E = ICE.get(); |
| 12340 | + } |
| 12341 | + |
| 12342 | + if (IntelFPGAPrivateCopiesAttr::classof(&TmpAttr)) { |
| 12343 | + if (!D->hasAttr<IntelFPGAMemoryAttr>()) |
| 12344 | + D->addAttr(IntelFPGAMemoryAttr::CreateImplicit( |
| 12345 | + Context, IntelFPGAMemoryAttr::Default)); |
| 12346 | + } |
| 12347 | + |
| 12348 | + D->addAttr(::new (Context) AttrType(Context, CI, E)); |
| 12349 | +} |
| 12350 | + |
| 12351 | +template <typename AttrType> |
| 12352 | +void Sema::AddOneConstantPowerTwoValueAttr(Decl *D, |
| 12353 | + const AttributeCommonInfo &CI, |
| 12354 | + Expr *E) { |
| 12355 | + AttrType TmpAttr(Context, CI, E); |
| 12356 | + |
| 12357 | + if (!E->isValueDependent()) { |
| 12358 | + ExprResult ICE; |
| 12359 | + if (checkRangedIntegralArgument<AttrType>(E, &TmpAttr, ICE)) |
| 12360 | + return; |
| 12361 | + Expr::EvalResult Result; |
| 12362 | + E->EvaluateAsInt(Result, Context); |
| 12363 | + llvm::APSInt Value = Result.Val.getInt(); |
| 12364 | + if (!Value.isPowerOf2()) { |
| 12365 | + Diag(CI.getLoc(), diag::err_attribute_argument_not_power_of_two) |
| 12366 | + << &TmpAttr; |
| 12367 | + return; |
| 12368 | + } |
| 12369 | + if (IntelFPGANumBanksAttr::classof(&TmpAttr)) { |
| 12370 | + if (auto *BBA = D->getAttr<IntelFPGABankBitsAttr>()) { |
| 12371 | + unsigned NumBankBits = BBA->args_size(); |
| 12372 | + if (NumBankBits != Value.ceilLogBase2()) { |
| 12373 | + Diag(TmpAttr.getLocation(), diag::err_bankbits_numbanks_conflicting); |
| 12374 | + return; |
| 12375 | + } |
| 12376 | + } |
| 12377 | + } |
| 12378 | + E = ICE.get(); |
| 12379 | + } |
| 12380 | + |
| 12381 | + if (!D->hasAttr<IntelFPGAMemoryAttr>()) |
| 12382 | + D->addAttr(IntelFPGAMemoryAttr::CreateImplicit( |
| 12383 | + Context, IntelFPGAMemoryAttr::Default)); |
| 12384 | + |
| 12385 | + // We are adding a user NumBanks, drop any implicit default. |
| 12386 | + if (IntelFPGANumBanksAttr::classof(&TmpAttr)) { |
| 12387 | + if (auto *NBA = D->getAttr<IntelFPGANumBanksAttr>()) |
| 12388 | + if (NBA->isImplicit()) |
| 12389 | + D->dropAttr<IntelFPGANumBanksAttr>(); |
| 12390 | + } |
| 12391 | + |
| 12392 | + D->addAttr(::new (Context) AttrType(Context, CI, E)); |
| 12393 | +} |
| 12394 | + |
12329 | 12395 | /// RAII object that enters a new expression evaluation context.
|
12330 | 12396 | class EnterExpressionEvaluationContext {
|
12331 | 12397 | Sema &Actions;
|
|
0 commit comments