Skip to content

Commit 33ff936

Browse files
committed
[SYCL] Cumulative patch
Signed-off-by: Vladimir Lazarev <[email protected]>
1 parent 51c2fd8 commit 33ff936

File tree

16 files changed

+963
-106
lines changed

16 files changed

+963
-106
lines changed

clang/include/clang/AST/PrettyPrinter.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ struct PrintingPolicy {
5151
MSWChar(LO.MicrosoftExt && !LO.WChar), IncludeNewlines(true),
5252
MSVCFormatting(false), ConstantsAsWritten(false),
5353
SuppressImplicitBase(false), FullyQualifiedName(false),
54-
RemapFilePaths(false), PrintCanonicalTypes(false) {}
54+
RemapFilePaths(false), PrintCanonicalTypes(false),
55+
SuppressDefinition(false) {}
5556

5657
/// Adjust this printing policy for cases where it's known that we're
5758
/// printing C++ code (for instance, if AST dumping reaches a C++-only
@@ -63,6 +64,13 @@ struct PrintingPolicy {
6364
UseVoidForZeroParams = false;
6465
}
6566

67+
/// Adjust this printing policy to print C++ forward declaration for a given
68+
/// Decl.
69+
void adjustForCPlusPlusFwdDecl() {
70+
PolishForDeclaration = true;
71+
SuppressDefinition = true;
72+
}
73+
6674
/// The number of spaces to use to indent each line.
6775
unsigned Indentation : 8;
6876

@@ -233,6 +241,17 @@ struct PrintingPolicy {
233241

234242
/// When RemapFilePaths is true, this function performs the action.
235243
std::function<std::string(StringRef)> remapPath;
244+
245+
/// When true does not print definition of a type. E.g.
246+
/// \code
247+
/// template<typename T> class C0 : public C1 {...}
248+
/// \endcode
249+
/// will be printed as
250+
/// \code
251+
/// template<typename T> class C0
252+
/// \endcode
253+
unsigned SuppressDefinition : 1;
254+
236255
};
237256

238257
} // end namespace clang

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9482,7 +9482,10 @@ def err_builtin_launder_invalid_arg : Error<
94829482
"%select{non-pointer|function pointer|void pointer}0 argument to "
94839483
"'__builtin_launder' is not allowed">;
94849484

9485+
// SYCL-specific diagnostics
94859486
def err_sycl_attribute_address_space_invalid : Error<
94869487
"address space is outside the valid range of values">;
9487-
9488+
def err_sycl_kernel_name_class_not_top_level : Error<
9489+
"kernel name class and its template argument classes' declarations can only "
9490+
"nest in a namespace: %0">;
94889491
} // end of sema component.

clang/include/clang/Sema/Sema.h

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ class SYCLIntegrationHeader {
307307
};
308308

309309
public:
310-
SYCLIntegrationHeader();
310+
SYCLIntegrationHeader(DiagnosticsEngine &Diag);
311311

312312
/// Emits contents of the header into given stream.
313313
void emit(raw_ostream &Out);
@@ -366,10 +366,28 @@ class SYCLIntegrationHeader {
366366
: nullptr;
367367
}
368368

369+
/// Emits a forward declaration for given declaration.
370+
void emitFwdDecl(raw_ostream &O, const Decl *D);
371+
372+
/// Emits forward declarations of classes and template classes on which
373+
/// declaration of given type depends. See example in the comments for the
374+
/// implementation.
375+
/// \param O
376+
/// stream to emit to
377+
/// \param T
378+
/// type to emit forward declarations for
379+
/// \param Emitted
380+
/// a set of declarations forward declrations has been emitted for already
381+
void emitForwardClassDecls(raw_ostream &O, QualType T,
382+
llvm::SmallPtrSetImpl<const void*> &Emitted);
383+
369384
private:
370385
/// Keeps invocation descriptors for each kernel invocation started by
371386
/// SYCLIntegrationHeader::startKernel
372387
SmallVector<KernelDesc, 4> KernelDescs;
388+
389+
/// Used for emitting diagnostics.
390+
DiagnosticsEngine &Diag;
373391
};
374392

375393
/// Sema - This implements semantic analysis and AST building for C.
@@ -10956,7 +10974,8 @@ class Sema {
1095610974
/// Lazily creates and returns SYCL integratrion header instance.
1095710975
SYCLIntegrationHeader &getSyclIntegrationHeader() {
1095810976
if (SyclIntHeader == nullptr)
10959-
SyclIntHeader = llvm::make_unique<SYCLIntegrationHeader>();
10977+
SyclIntHeader = llvm::make_unique<SYCLIntegrationHeader>(
10978+
getDiagnostics());
1096010979
return *SyclIntHeader.get();
1096110980
}
1096210981

clang/lib/AST/DeclPrinter.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,9 @@ void DeclPrinter::VisitEnumDecl(EnumDecl *D) {
514514

515515
Out << ' ' << *D;
516516

517+
if (Policy.SuppressDefinition)
518+
return;
519+
517520
if (D->isFixed() && D->getASTContext().getLangOpts().CPlusPlus11)
518521
Out << " : " << D->getIntegerType().stream(Policy);
519522

@@ -534,6 +537,9 @@ void DeclPrinter::VisitRecordDecl(RecordDecl *D) {
534537
if (D->getIdentifier())
535538
Out << ' ' << *D;
536539

540+
if (Policy.SuppressDefinition)
541+
return;
542+
537543
if (D->isCompleteDefinition()) {
538544
Out << " {\n";
539545
VisitDeclContext(D);
@@ -715,7 +721,7 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
715721
Out << " = delete";
716722
else if (D->isExplicitlyDefaulted())
717723
Out << " = default";
718-
else if (D->doesThisDeclarationHaveABody()) {
724+
else if (D->doesThisDeclarationHaveABody() && !Policy.SuppressDefinition) {
719725
if (!Policy.TerseOutput) {
720726
if (!D->hasPrototype() && D->getNumParams()) {
721727
// This is a K&R function definition, so we need to print the
@@ -931,7 +937,7 @@ void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) {
931937
printTemplateArguments(S->getTemplateArgs());
932938
}
933939

934-
if (D->isCompleteDefinition()) {
940+
if (D->isCompleteDefinition() && !Policy.SuppressDefinition) {
935941
// Print the base classes
936942
if (D->getNumBases()) {
937943
Out << " : ";

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 53 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -588,7 +588,7 @@ static std::string constructKernelName(QualType KernelNameType) {
588588
Pos = TStr.find(Kwd, Pos)) {
589589

590590
size_t EndPos = Pos + Kwd.length();
591-
if ((!llvm::isAlnum(TStr[Pos - 1])) &&
591+
if ((Pos == 0 || !llvm::isAlnum(TStr[Pos - 1])) &&
592592
(EndPos == TStr.length() || !llvm::isAlnum(TStr[EndPos]))) {
593593
// keyword is a separate word - erase
594594
TStr.erase(Pos, Kwd.length());
@@ -651,28 +651,55 @@ static const char *paramKind2Str(KernelParamKind K) {
651651
#undef CASE
652652
}
653653

654-
// Prints a declaration
655-
static void printDecl(raw_ostream &O, const Decl *D) {
656-
PrintingPolicy P(D->getASTContext().getLangOpts());
654+
// Emits a forward declaration
655+
void SYCLIntegrationHeader::emitFwdDecl(raw_ostream &O, const Decl *D) {
656+
// wrap the declaration into namespaces if needed
657+
unsigned NamespaceCnt = 0;
658+
std::string NSStr = "";
659+
const DeclContext *DC = D->getDeclContext();
660+
661+
while (DC) {
662+
auto *NS = dyn_cast_or_null<NamespaceDecl>(DC);
663+
664+
if (!NS) {
665+
if (!DC->isTranslationUnit()) {
666+
const TagDecl *TD = isa<ClassTemplateDecl>(D) ?
667+
cast<ClassTemplateDecl>(D)->getTemplatedDecl() : dyn_cast<TagDecl>(D);
668+
669+
if (TD && TD->isCompleteDefinition()) {
670+
// defied class constituting the kernel name is not globally
671+
// accessible - contradicts the spec
672+
Diag.Report(D->getSourceRange().getBegin(),
673+
diag::err_sycl_kernel_name_class_not_top_level);
674+
}
675+
}
676+
break;
677+
}
678+
++NamespaceCnt;
679+
NSStr.insert(0, Twine("namespace " + Twine(NS->getName()) + " { ").str());
680+
DC = NS->getDeclContext();
681+
}
682+
O << NSStr;
683+
if (NamespaceCnt > 0)
684+
O << "\n";
657685
// print declaration into a string:
658-
P.TerseOutput = true; // prints declaration plus " {}" in the end
659-
P.PolishForDeclaration = true;
686+
PrintingPolicy P(D->getASTContext().getLangOpts());
687+
P.adjustForCPlusPlusFwdDecl();
660688
std::string S;
661689
llvm::raw_string_ostream SO(S);
662690
D->print(SO, P);
663-
// print the declaration w/o the trailing " {}":
664-
StringRef SR = SO.str();
665-
size_t Pos = SR.find_first_of('{');
691+
O << SO.str() << ";\n";
666692

667-
if (Pos != StringRef::npos) {
668-
// can be npos if the type is incomplete
669-
SR = SR.take_front(Pos);
670-
}
671-
O << SR;
693+
// print closing braces for namespaces if needed
694+
for (unsigned I = 0; I < NamespaceCnt; ++I)
695+
O << "}";
696+
if (NamespaceCnt > 0)
697+
O << "\n";
672698
}
673699

674700
// Emits forward declarations of classes and template classes on which
675-
// declaration of given type depends. For example, consider SimpleVadd
701+
// declaration of given type depends.
702+
// For example, consider SimpleVadd
676703
// class specialization in parallel_for below:
677704
//
678705
// template <typename T1, unsigned int N, typename ... T2>
@@ -705,20 +732,9 @@ static void printDecl(raw_ostream &O, const Decl *D) {
705732
// template <typename T> class MyTmplClass;
706733
// template <typename T1, unsigned int N, typename ...T2> class SimpleVadd;
707734
//
708-
// TODO FIXME handle the case when kernel typename is declared in a namespace
709-
//
710-
// \param O
711-
// stream to print to
712-
// \param T
713-
// type to emit forward declarations for
714-
// \param Printed
715-
// a set of type pointers forward declrations has been printed for already
716-
// \param Depth
717-
// recursion depth
718-
//
719-
static void
720-
emitForwardClassDecls(raw_ostream &O, QualType T,
721-
llvm::SmallPtrSetImpl<const void *> &Printed) {
735+
void SYCLIntegrationHeader::emitForwardClassDecls(raw_ostream &O,
736+
QualType T,
737+
llvm::SmallPtrSetImpl<const void*> &Printed) {
722738

723739
// peel off the pointer types and get the class/struct type:
724740
for (; T->isPointerType(); T = T->getPointeeType())
@@ -764,15 +780,13 @@ emitForwardClassDecls(raw_ostream &O, QualType T,
764780
assert(CTD && "template declaration must be available");
765781

766782
if (Printed.insert(CTD).second) {
767-
printDecl(O, CTD);
768-
O << ";\n";
783+
emitFwdDecl(O, CTD);
769784
}
770-
} else if (Printed.insert(RD).second) {
785+
}
786+
else if (Printed.insert(RD).second) {
771787
// emit forward declarations for "leaf" classes in the template parameter
772-
// tree; Depth > 0: don't print forward decl for top level non-templated
773-
// class
774-
printDecl(O, RD);
775-
O << ";\n";
788+
// tree;
789+
emitFwdDecl(O, RD);
776790
}
777791
}
778792

@@ -918,4 +932,6 @@ void SYCLIntegrationHeader::endKernel() {
918932
// nop for now
919933
}
920934

921-
SYCLIntegrationHeader::SYCLIntegrationHeader() {}
935+
SYCLIntegrationHeader::SYCLIntegrationHeader(DiagnosticsEngine &_Diag)
936+
: Diag(_Diag) {}
937+

0 commit comments

Comments
 (0)