/// Checks whether 'sym' has the @ldc.attributes._weak() UDA applied. bool hasWeakUDA(Dsymbol *sym) { if (!sym->userAttribDecl) return false; // Loop over all UDAs and early return true if @weak was found. Expressions *attrs = sym->userAttribDecl->getAttributes(); expandTuples(attrs); for (auto &attr : *attrs) { auto sle = getLdcAttributesStruct(attr); if (!sle) continue; auto name = sle->sd->ident->string; if (name == attr::weak) { // Check whether @weak can be applied to this symbol. // Because hasWeakUDA is currently only called for global symbols, this check never errors. auto vd = sym->isVarDeclaration(); if (!(vd && vd->isDataseg()) && !sym->isFuncDeclaration()) { sym->error("@ldc.attributes.weak can only be applied to functions or global variables"); return false; } return true; } } return false; }
void applyFuncDeclUDAs(FuncDeclaration *decl, IrFunction *irFunc) { if (!decl->userAttribDecl) return; llvm::Function *func = irFunc->func; assert(func); Expressions *attrs = decl->userAttribDecl->getAttributes(); expandTuples(attrs); for (auto &attr : *attrs) { auto sle = getLdcAttributesStruct(attr); if (!sle) continue; auto name = sle->sd->ident->string; if (name == attr::llvmAttr) { applyAttrLLVMAttr(sle, func); } else if (name == attr::llvmFastMathFlag) { applyAttrLLVMFastMathFlag(sle, irFunc); } else if (name == attr::optStrategy) { applyAttrOptStrategy(sle, irFunc); } else if (name == attr::section) { applyAttrSection(sle, func); } else if (name == attr::target) { applyAttrTarget(sle, func); } else if (name == attr::weak) { // @weak is applied elsewhere } else { sle->warning( "ignoring unrecognized special attribute 'ldc.attributes.%s'", sle->sd->ident->string); } } }
void applyVarDeclUDAs(VarDeclaration *decl, llvm::GlobalVariable *gvar) { if (!decl->userAttribDecl) return; Expressions *attrs = decl->userAttribDecl->getAttributes(); expandTuples(attrs); for (auto &attr : *attrs) { auto sle = getLdcAttributesStruct(attr); if (!sle) continue; auto name = sle->sd->ident->string; if (name == attr::section) { applyAttrSection(sle, gvar); } else if (name == attr::optStrategy) { sle->error( "Special attribute 'ldc.attributes.optStrategy' is only valid for " "functions"); } else if (name == attr::target) { sle->error("Special attribute 'ldc.attributes.target' is only valid for " "functions"); } else if (name == attr::weak) { // @weak is applied elsewhere } else { sle->warning( "Ignoring unrecognized special attribute 'ldc.attributes.%s'", sle->sd->ident->string); } } }
void applyVarDeclUDAs(VarDeclaration *decl, llvm::GlobalVariable *gvar) { if (!decl->userAttribDecl) return; Expressions *attrs = decl->userAttribDecl->getAttributes(); expandTuples(attrs); for (auto &attr : *attrs) { auto sle = getLdcAttributesStruct(attr); if (!sle) continue; auto ident = sle->sd->ident; if (ident == Id::udaSection) { applyAttrSection(sle, gvar); } else if (ident == Id::udaOptStrategy || ident == Id::udaTarget) { sle->error( "Special attribute `ldc.attributes.%s` is only valid for functions", ident->toChars()); } else if (ident == Id::udaAssumeUsed) { applyAttrAssumeUsed(*gIR, sle, gvar); } else if (ident == Id::udaWeak) { // @weak is applied elsewhere } else if (ident == Id::udaDynamicCompile) { sle->error( "Special attribute `ldc.attributes.%s` is only valid for functions", ident->toChars()); } else if (ident == Id::udaDynamicCompileConst) { getIrGlobal(decl)->dynamicCompileConst = true; } else { sle->warning( "Ignoring unrecognized special attribute `ldc.attributes.%s`", ident->toChars()); } } }
void applyFuncDeclUDAs(FuncDeclaration *decl, IrFunction *irFunc) { if (!decl->userAttribDecl) return; llvm::Function *func = irFunc->getLLVMFunc(); assert(func); Expressions *attrs = decl->userAttribDecl->getAttributes(); expandTuples(attrs); for (auto &attr : *attrs) { auto sle = getLdcAttributesStruct(attr); if (!sle) continue; auto ident = sle->sd->ident; if (ident == Id::udaAllocSize) { applyAttrAllocSize(sle, irFunc); } else if (ident == Id::udaLLVMAttr) { applyAttrLLVMAttr(sle, func); } else if (ident == Id::udaLLVMFastMathFlag) { applyAttrLLVMFastMathFlag(sle, irFunc); } else if (ident == Id::udaOptStrategy) { applyAttrOptStrategy(sle, irFunc); } else if (ident == Id::udaSection) { applyAttrSection(sle, func); } else if (ident == Id::udaTarget) { applyAttrTarget(sle, func, irFunc); } else if (ident == Id::udaAssumeUsed) { applyAttrAssumeUsed(*gIR, sle, func); } else if (ident == Id::udaWeak || ident == Id::udaKernel) { // @weak and @kernel are applied elsewhere } else if (ident == Id::udaDynamicCompile) { irFunc->dynamicCompile = true; } else if (ident == Id::udaDynamicCompileConst) { sle->error( "Special attribute `ldc.attributes.%s` is only valid for variables", ident->toChars()); } else { sle->warning( "Ignoring unrecognized special attribute `ldc.attributes.%s`", ident->toChars()); } } }