@@ -7640,6 +7640,59 @@ static bool isMainVar(DeclarationName Name, VarDecl *VD) {
7640
7640
VD->isExternC());
7641
7641
}
7642
7642
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,
7680
+ Context.getTypeSize(R),
7681
+ HasSizeMismatch))
7682
+ Diag(E->getExprLoc(), diag::err_asm_invalid_global_var_reg) << Label;
7683
+ else if (HasSizeMismatch)
7684
+ Diag(E->getExprLoc(), diag::err_asm_register_size_mismatch) << Label;
7685
+ }
7686
+
7687
+ if (!R->isIntegralType(Context) && !R->isPointerType()) {
7688
+ Diag(TInfo->getTypeLoc().getBeginLoc(),
7689
+ diag::err_asm_unsupported_register_type)
7690
+ << TInfo->getTypeLoc().getSourceRange();
7691
+ NewVD->setInvalidDecl(true);
7692
+ }
7693
+ }
7694
+ }
7695
+
7643
7696
NamedDecl *Sema::ActOnVariableDeclarator(
7644
7697
Scope *S, Declarator &D, DeclContext *DC, TypeSourceInfo *TInfo,
7645
7698
LookupResult &Previous, MultiTemplateParamsArg TemplateParamLists,
@@ -8124,6 +8177,26 @@ NamedDecl *Sema::ActOnVariableDeclarator(
8124
8177
}
8125
8178
}
8126
8179
8180
+ if (Expr *E = D.getAsmLabel()) {
8181
+ // The parser guarantees this is a string.
8182
+ StringLiteral *SE = cast<StringLiteral>(E);
8183
+ StringRef Label = SE->getString();
8184
+
8185
+ // Insert the asm attribute.
8186
+ NewVD->addAttr(AsmLabelAttr::Create(Context, Label, SE->getStrTokenLoc(0)));
8187
+ } else if (!ExtnameUndeclaredIdentifiers.empty()) {
8188
+ llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I =
8189
+ ExtnameUndeclaredIdentifiers.find(NewVD->getIdentifier());
8190
+ if (I != ExtnameUndeclaredIdentifiers.end()) {
8191
+ if (isDeclExternC(NewVD)) {
8192
+ NewVD->addAttr(I->second);
8193
+ ExtnameUndeclaredIdentifiers.erase(I);
8194
+ } else
8195
+ Diag(NewVD->getLocation(), diag::warn_redefine_extname_not_applied)
8196
+ << /*Variable*/1 << NewVD;
8197
+ }
8198
+ }
8199
+
8127
8200
// Handle attributes prior to checking for duplicates in MergeVarDecl
8128
8201
ProcessDeclAttributes(S, NewVD, D);
8129
8202
@@ -8174,65 +8247,11 @@ NamedDecl *Sema::ActOnVariableDeclarator(
8174
8247
if (getLangOpts().ObjCAutoRefCount && ObjC().inferObjCARCLifetime(NewVD))
8175
8248
NewVD->setInvalidDecl();
8176
8249
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
- }
8250
+ // Check the ASM label here, as we need to know all other attributes of the
8251
+ // Decl first. Otherwise, we can't know if the asm label refers to the
8252
+ // host or device in a CUDA context. The device has other registers than
8253
+ // host and we must know where the function will be placed.
8254
+ CheckAsmLabel(S, D.getAsmLabel(), SC, TInfo, NewVD);
8236
8255
8237
8256
// Find the shadowed declaration before filtering for scope.
8238
8257
NamedDecl *ShadowedDecl = D.getCXXScopeSpec().isEmpty()
0 commit comments