@@ -7640,6 +7640,58 @@ static bool isMainVar(DeclarationName Name, VarDecl *VD) {
76407640 VD->isExternC());
76417641}
76427642
7643+ void Sema::CheckAsmLabel(Scope *S, Expr *E, StorageClass SC,
7644+ TypeSourceInfo *TInfo, VarDecl *NewVD) {
7645+
7646+ // Quickly return if the function does not have an `asm` attribute.
7647+ if (E == nullptr)
7648+ return;
7649+
7650+ // The parser guarantees this is a string.
7651+ StringLiteral *SE = cast<StringLiteral>(E);
7652+ StringRef Label = SE->getString();
7653+ QualType R = TInfo->getType();
7654+ if (S->getFnParent() != nullptr) {
7655+ switch (SC) {
7656+ case SC_None:
7657+ case SC_Auto:
7658+ Diag(E->getExprLoc(), diag::warn_asm_label_on_auto_decl) << Label;
7659+ break;
7660+ case SC_Register:
7661+ // Local Named register
7662+ if (!Context.getTargetInfo().isValidGCCRegisterName(Label) &&
7663+ DeclAttrsMatchCUDAMode(getLangOpts(), getCurFunctionDecl()))
7664+ Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label;
7665+ break;
7666+ case SC_Static:
7667+ case SC_Extern:
7668+ case SC_PrivateExtern:
7669+ break;
7670+ }
7671+ } else if (SC == SC_Register) {
7672+ // Global Named register
7673+ if (DeclAttrsMatchCUDAMode(getLangOpts(), NewVD)) {
7674+ const auto &TI = Context.getTargetInfo();
7675+ bool HasSizeMismatch;
7676+
7677+ if (!TI.isValidGCCRegisterName(Label))
7678+ Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label;
7679+ else if (!TI.validateGlobalRegisterVariable(Label, Context.getTypeSize(R),
7680+ HasSizeMismatch))
7681+ Diag(E->getExprLoc(), diag::err_asm_invalid_global_var_reg) << Label;
7682+ else if (HasSizeMismatch)
7683+ Diag(E->getExprLoc(), diag::err_asm_register_size_mismatch) << Label;
7684+ }
7685+
7686+ if (!R->isIntegralType(Context) && !R->isPointerType()) {
7687+ Diag(TInfo->getTypeLoc().getBeginLoc(),
7688+ diag::err_asm_unsupported_register_type)
7689+ << TInfo->getTypeLoc().getSourceRange();
7690+ NewVD->setInvalidDecl(true);
7691+ }
7692+ }
7693+ }
7694+
76437695NamedDecl *Sema::ActOnVariableDeclarator(
76447696 Scope *S, Declarator &D, DeclContext *DC, TypeSourceInfo *TInfo,
76457697 LookupResult &Previous, MultiTemplateParamsArg TemplateParamLists,
@@ -8124,6 +8176,26 @@ NamedDecl *Sema::ActOnVariableDeclarator(
81248176 }
81258177 }
81268178
8179+ if (Expr *E = D.getAsmLabel()) {
8180+ // The parser guarantees this is a string.
8181+ StringLiteral *SE = cast<StringLiteral>(E);
8182+ StringRef Label = SE->getString();
8183+
8184+ // Insert the asm attribute.
8185+ NewVD->addAttr(AsmLabelAttr::Create(Context, Label, SE->getStrTokenLoc(0)));
8186+ } else if (!ExtnameUndeclaredIdentifiers.empty()) {
8187+ llvm::DenseMap<IdentifierInfo *, AsmLabelAttr *>::iterator I =
8188+ ExtnameUndeclaredIdentifiers.find(NewVD->getIdentifier());
8189+ if (I != ExtnameUndeclaredIdentifiers.end()) {
8190+ if (isDeclExternC(NewVD)) {
8191+ NewVD->addAttr(I->second);
8192+ ExtnameUndeclaredIdentifiers.erase(I);
8193+ } else
8194+ Diag(NewVD->getLocation(), diag::warn_redefine_extname_not_applied)
8195+ << /*Variable*/ 1 << NewVD;
8196+ }
8197+ }
8198+
81278199 // Handle attributes prior to checking for duplicates in MergeVarDecl
81288200 ProcessDeclAttributes(S, NewVD, D);
81298201
@@ -8174,65 +8246,11 @@ NamedDecl *Sema::ActOnVariableDeclarator(
81748246 if (getLangOpts().ObjCAutoRefCount && ObjC().inferObjCARCLifetime(NewVD))
81758247 NewVD->setInvalidDecl();
81768248
8177- // Handle GNU asm-label extension (encoded as an attribute).
8178- if (Expr *E = D.getAsmLabel()) {
8179- // The parser guarantees this is a string.
8180- StringLiteral *SE = cast<StringLiteral>(E);
8181- StringRef Label = SE->getString();
8182- if (S->getFnParent() != nullptr) {
8183- switch (SC) {
8184- case SC_None:
8185- case SC_Auto:
8186- Diag(E->getExprLoc(), diag::warn_asm_label_on_auto_decl) << Label;
8187- break;
8188- case SC_Register:
8189- // Local Named register
8190- if (!Context.getTargetInfo().isValidGCCRegisterName(Label) &&
8191- DeclAttrsMatchCUDAMode(getLangOpts(), getCurFunctionDecl()))
8192- Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label;
8193- break;
8194- case SC_Static:
8195- case SC_Extern:
8196- case SC_PrivateExtern:
8197- break;
8198- }
8199- } else if (SC == SC_Register) {
8200- // Global Named register
8201- if (DeclAttrsMatchCUDAMode(getLangOpts(), NewVD)) {
8202- const auto &TI = Context.getTargetInfo();
8203- bool HasSizeMismatch;
8204-
8205- if (!TI.isValidGCCRegisterName(Label))
8206- Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label;
8207- else if (!TI.validateGlobalRegisterVariable(Label,
8208- Context.getTypeSize(R),
8209- HasSizeMismatch))
8210- Diag(E->getExprLoc(), diag::err_asm_invalid_global_var_reg) << Label;
8211- else if (HasSizeMismatch)
8212- Diag(E->getExprLoc(), diag::err_asm_register_size_mismatch) << Label;
8213- }
8214-
8215- if (!R->isIntegralType(Context) && !R->isPointerType()) {
8216- Diag(TInfo->getTypeLoc().getBeginLoc(),
8217- diag::err_asm_unsupported_register_type)
8218- << TInfo->getTypeLoc().getSourceRange();
8219- NewVD->setInvalidDecl(true);
8220- }
8221- }
8222-
8223- NewVD->addAttr(AsmLabelAttr::Create(Context, Label, SE->getStrTokenLoc(0)));
8224- } else if (!ExtnameUndeclaredIdentifiers.empty()) {
8225- llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I =
8226- ExtnameUndeclaredIdentifiers.find(NewVD->getIdentifier());
8227- if (I != ExtnameUndeclaredIdentifiers.end()) {
8228- if (isDeclExternC(NewVD)) {
8229- NewVD->addAttr(I->second);
8230- ExtnameUndeclaredIdentifiers.erase(I);
8231- } else
8232- Diag(NewVD->getLocation(), diag::warn_redefine_extname_not_applied)
8233- << /*Variable*/1 << NewVD;
8234- }
8235- }
8249+ // Check the ASM label here, as we need to know all other attributes of the
8250+ // Decl first. Otherwise, we can't know if the asm label refers to the
8251+ // host or device in a CUDA context. The device has other registers than
8252+ // host and we must know where the function will be placed.
8253+ CheckAsmLabel(S, D.getAsmLabel(), SC, TInfo, NewVD);
82368254
82378255 // Find the shadowed declaration before filtering for scope.
82388256 NamedDecl *ShadowedDecl = D.getCXXScopeSpec().isEmpty()
0 commit comments