Skip to content

Commit

Permalink
[SYCL] Cumulative patch
Browse files Browse the repository at this point in the history
Signed-off-by: Vladimir Lazarev <vladimir.lazarev@intel.com>
  • Loading branch information
vladimirlaz committed Jan 22, 2019
1 parent 51c2fd8 commit 33ff936
Show file tree
Hide file tree
Showing 16 changed files with 963 additions and 106 deletions.
21 changes: 20 additions & 1 deletion clang/include/clang/AST/PrettyPrinter.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ struct PrintingPolicy {
MSWChar(LO.MicrosoftExt && !LO.WChar), IncludeNewlines(true),
MSVCFormatting(false), ConstantsAsWritten(false),
SuppressImplicitBase(false), FullyQualifiedName(false),
RemapFilePaths(false), PrintCanonicalTypes(false) {}
RemapFilePaths(false), PrintCanonicalTypes(false),
SuppressDefinition(false) {}

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

/// Adjust this printing policy to print C++ forward declaration for a given
/// Decl.
void adjustForCPlusPlusFwdDecl() {
PolishForDeclaration = true;
SuppressDefinition = true;
}

/// The number of spaces to use to indent each line.
unsigned Indentation : 8;

Expand Down Expand Up @@ -233,6 +241,17 @@ struct PrintingPolicy {

/// When RemapFilePaths is true, this function performs the action.
std::function<std::string(StringRef)> remapPath;

/// When true does not print definition of a type. E.g.
/// \code
/// template<typename T> class C0 : public C1 {...}
/// \endcode
/// will be printed as
/// \code
/// template<typename T> class C0
/// \endcode
unsigned SuppressDefinition : 1;

};

} // end namespace clang
Expand Down
5 changes: 4 additions & 1 deletion clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -9482,7 +9482,10 @@ def err_builtin_launder_invalid_arg : Error<
"%select{non-pointer|function pointer|void pointer}0 argument to "
"'__builtin_launder' is not allowed">;

// SYCL-specific diagnostics
def err_sycl_attribute_address_space_invalid : Error<
"address space is outside the valid range of values">;

def err_sycl_kernel_name_class_not_top_level : Error<
"kernel name class and its template argument classes' declarations can only "
"nest in a namespace: %0">;
} // end of sema component.
23 changes: 21 additions & 2 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ class SYCLIntegrationHeader {
};

public:
SYCLIntegrationHeader();
SYCLIntegrationHeader(DiagnosticsEngine &Diag);

/// Emits contents of the header into given stream.
void emit(raw_ostream &Out);
Expand Down Expand Up @@ -366,10 +366,28 @@ class SYCLIntegrationHeader {
: nullptr;
}

/// Emits a forward declaration for given declaration.
void emitFwdDecl(raw_ostream &O, const Decl *D);

/// Emits forward declarations of classes and template classes on which
/// declaration of given type depends. See example in the comments for the
/// implementation.
/// \param O
/// stream to emit to
/// \param T
/// type to emit forward declarations for
/// \param Emitted
/// a set of declarations forward declrations has been emitted for already
void emitForwardClassDecls(raw_ostream &O, QualType T,
llvm::SmallPtrSetImpl<const void*> &Emitted);

private:
/// Keeps invocation descriptors for each kernel invocation started by
/// SYCLIntegrationHeader::startKernel
SmallVector<KernelDesc, 4> KernelDescs;

/// Used for emitting diagnostics.
DiagnosticsEngine &Diag;
};

/// Sema - This implements semantic analysis and AST building for C.
Expand Down Expand Up @@ -10956,7 +10974,8 @@ class Sema {
/// Lazily creates and returns SYCL integratrion header instance.
SYCLIntegrationHeader &getSyclIntegrationHeader() {
if (SyclIntHeader == nullptr)
SyclIntHeader = llvm::make_unique<SYCLIntegrationHeader>();
SyclIntHeader = llvm::make_unique<SYCLIntegrationHeader>(
getDiagnostics());
return *SyclIntHeader.get();
}

Expand Down
10 changes: 8 additions & 2 deletions clang/lib/AST/DeclPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,9 @@ void DeclPrinter::VisitEnumDecl(EnumDecl *D) {

Out << ' ' << *D;

if (Policy.SuppressDefinition)
return;

if (D->isFixed() && D->getASTContext().getLangOpts().CPlusPlus11)
Out << " : " << D->getIntegerType().stream(Policy);

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

if (Policy.SuppressDefinition)
return;

if (D->isCompleteDefinition()) {
Out << " {\n";
VisitDeclContext(D);
Expand Down Expand Up @@ -715,7 +721,7 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
Out << " = delete";
else if (D->isExplicitlyDefaulted())
Out << " = default";
else if (D->doesThisDeclarationHaveABody()) {
else if (D->doesThisDeclarationHaveABody() && !Policy.SuppressDefinition) {
if (!Policy.TerseOutput) {
if (!D->hasPrototype() && D->getNumParams()) {
// This is a K&R function definition, so we need to print the
Expand Down Expand Up @@ -931,7 +937,7 @@ void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) {
printTemplateArguments(S->getTemplateArgs());
}

if (D->isCompleteDefinition()) {
if (D->isCompleteDefinition() && !Policy.SuppressDefinition) {
// Print the base classes
if (D->getNumBases()) {
Out << " : ";
Expand Down
90 changes: 53 additions & 37 deletions clang/lib/Sema/SemaSYCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,7 @@ static std::string constructKernelName(QualType KernelNameType) {
Pos = TStr.find(Kwd, Pos)) {

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

// Prints a declaration
static void printDecl(raw_ostream &O, const Decl *D) {
PrintingPolicy P(D->getASTContext().getLangOpts());
// Emits a forward declaration
void SYCLIntegrationHeader::emitFwdDecl(raw_ostream &O, const Decl *D) {
// wrap the declaration into namespaces if needed
unsigned NamespaceCnt = 0;
std::string NSStr = "";
const DeclContext *DC = D->getDeclContext();

while (DC) {
auto *NS = dyn_cast_or_null<NamespaceDecl>(DC);

if (!NS) {
if (!DC->isTranslationUnit()) {
const TagDecl *TD = isa<ClassTemplateDecl>(D) ?
cast<ClassTemplateDecl>(D)->getTemplatedDecl() : dyn_cast<TagDecl>(D);

if (TD && TD->isCompleteDefinition()) {
// defied class constituting the kernel name is not globally
// accessible - contradicts the spec
Diag.Report(D->getSourceRange().getBegin(),
diag::err_sycl_kernel_name_class_not_top_level);
}
}
break;
}
++NamespaceCnt;
NSStr.insert(0, Twine("namespace " + Twine(NS->getName()) + " { ").str());
DC = NS->getDeclContext();
}
O << NSStr;
if (NamespaceCnt > 0)
O << "\n";
// print declaration into a string:
P.TerseOutput = true; // prints declaration plus " {}" in the end
P.PolishForDeclaration = true;
PrintingPolicy P(D->getASTContext().getLangOpts());
P.adjustForCPlusPlusFwdDecl();
std::string S;
llvm::raw_string_ostream SO(S);
D->print(SO, P);
// print the declaration w/o the trailing " {}":
StringRef SR = SO.str();
size_t Pos = SR.find_first_of('{');
O << SO.str() << ";\n";

if (Pos != StringRef::npos) {
// can be npos if the type is incomplete
SR = SR.take_front(Pos);
}
O << SR;
// print closing braces for namespaces if needed
for (unsigned I = 0; I < NamespaceCnt; ++I)
O << "}";
if (NamespaceCnt > 0)
O << "\n";
}

// Emits forward declarations of classes and template classes on which
// declaration of given type depends. For example, consider SimpleVadd
// declaration of given type depends.
// For example, consider SimpleVadd
// class specialization in parallel_for below:
//
// template <typename T1, unsigned int N, typename ... T2>
Expand Down Expand Up @@ -705,20 +732,9 @@ static void printDecl(raw_ostream &O, const Decl *D) {
// template <typename T> class MyTmplClass;
// template <typename T1, unsigned int N, typename ...T2> class SimpleVadd;
//
// TODO FIXME handle the case when kernel typename is declared in a namespace
//
// \param O
// stream to print to
// \param T
// type to emit forward declarations for
// \param Printed
// a set of type pointers forward declrations has been printed for already
// \param Depth
// recursion depth
//
static void
emitForwardClassDecls(raw_ostream &O, QualType T,
llvm::SmallPtrSetImpl<const void *> &Printed) {
void SYCLIntegrationHeader::emitForwardClassDecls(raw_ostream &O,
QualType T,
llvm::SmallPtrSetImpl<const void*> &Printed) {

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

if (Printed.insert(CTD).second) {
printDecl(O, CTD);
O << ";\n";
emitFwdDecl(O, CTD);
}
} else if (Printed.insert(RD).second) {
}
else if (Printed.insert(RD).second) {
// emit forward declarations for "leaf" classes in the template parameter
// tree; Depth > 0: don't print forward decl for top level non-templated
// class
printDecl(O, RD);
O << ";\n";
// tree;
emitFwdDecl(O, RD);
}
}

Expand Down Expand Up @@ -918,4 +932,6 @@ void SYCLIntegrationHeader::endKernel() {
// nop for now
}

SYCLIntegrationHeader::SYCLIntegrationHeader() {}
SYCLIntegrationHeader::SYCLIntegrationHeader(DiagnosticsEngine &_Diag)
: Diag(_Diag) {}

Loading

0 comments on commit 33ff936

Please sign in to comment.