diff options
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 64352ab..160d735 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -3115,6 +3115,10 @@ static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) { cast<SYCLKernelEntryPointAttr>(NewAttribute)->setInvalidAttr(); ++I; continue; + } else if (isa<SYCLExternalAttr>(NewAttribute)) { + // SYCLExternalAttr may be added after a definition. + ++I; + continue; } S.Diag(NewAttribute->getLocation(), @@ -4140,6 +4144,18 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, Scope *S, diag::note_carries_dependency_missing_first_decl) << 0/*Function*/; } + // SYCL 2020 section 5.10.1, "SYCL functions and member functions linkage": + // When a function is declared with SYCL_EXTERNAL, that macro must be + // used on the first declaration of that function in the translation unit. + // Redeclarations of the function in the same translation unit may + // optionally use SYCL_EXTERNAL, but this is not required. + const SYCLExternalAttr *SEA = New->getAttr<SYCLExternalAttr>(); + if (SEA && !Old->hasAttr<SYCLExternalAttr>()) { + Diag(SEA->getLocation(), diag::warn_sycl_external_missing_on_first_decl) + << SEA; + Diag(Old->getLocation(), diag::note_previous_declaration); + } + // (C++98 8.3.5p3): // All declarations for a function shall agree exactly in both the // return type and the parameter-type-list. @@ -12325,6 +12341,9 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, if (NewFD->hasAttr<SYCLKernelEntryPointAttr>()) SYCL().CheckSYCLEntryPointFunctionDecl(NewFD); + if (NewFD->hasAttr<SYCLExternalAttr>()) + SYCL().CheckSYCLExternalFunctionDecl(NewFD); + // Semantic checking for this function declaration (in isolation). if (getLangOpts().CPlusPlus) { @@ -12513,6 +12532,13 @@ void Sema::CheckMain(FunctionDecl *FD, const DeclSpec &DS) { return; } + if (FD->hasAttr<SYCLExternalAttr>()) { + Diag(FD->getLocation(), diag::err_sycl_external_invalid_main) + << FD->getAttr<SYCLExternalAttr>(); + FD->setInvalidDecl(); + return; + } + // Functions named main in hlsl are default entries, but don't have specific // signatures they are required to conform to. if (getLangOpts().HLSL) @@ -16351,6 +16377,14 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, bool IsInstantiation, } } + if (FD && !FD->isInvalidDecl() && FD->hasAttr<SYCLExternalAttr>()) { + SYCLExternalAttr *SEAttr = FD->getAttr<SYCLExternalAttr>(); + if (FD->isDeletedAsWritten()) + Diag(SEAttr->getLocation(), + diag::err_sycl_external_invalid_deleted_function) + << SEAttr; + } + { // Do not call PopExpressionEvaluationContext() if it is a lambda because // one is already popped when finishing the lambda in BuildLambdaExpr(). |