Meinersbur updated this revision to Diff 228297.
Meinersbur added a comment.

- Switch to monorepo
- Move Transform.h/cpp to clangBasic
- Separate Transform and TransformClause


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69089/new/

https://reviews.llvm.org/D69089

Files:
  clang/include/clang/AST/StmtTransform.h
  clang/include/clang/AST/TransformClauseKinds.def
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticParseKinds.td
  clang/include/clang/Basic/Transform.h
  clang/include/clang/Basic/TransformKinds.def
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/CMakeLists.txt
  clang/lib/AST/StmtTransform.cpp
  clang/lib/Basic/CMakeLists.txt
  clang/lib/Basic/Transform.cpp
  clang/lib/Parse/CMakeLists.txt
  clang/lib/Parse/ParseStmt.cpp
  clang/lib/Parse/ParseTransform.cpp
  clang/lib/Sema/CMakeLists.txt
  clang/lib/Sema/SemaTransform.cpp
  clang/test/Parser/pragma-transform.cpp

Index: clang/test/Parser/pragma-transform.cpp
===================================================================
--- /dev/null
+++ clang/test/Parser/pragma-transform.cpp
@@ -0,0 +1,92 @@
+// RUN: %clang_cc1 -std=c++11 -fexperimental-transform-pragma -verify %s
+
+void pragma_transform(int *List, int Length) {
+// FIXME: This does not emit an error
+#pragma clang
+
+/* expected-error@+1 {{expected a transformation name}} */
+#pragma clang transform
+  for (int i = 0; i < Length; i+=1)
+      List[i] = i;
+
+/* expected-error@+1 {{unknown transformation}} */
+#pragma clang transform unknown_transformation
+  for (int i = 0; i < Length; i+=1)
+      List[i] = i;
+
+/* expected-error@+2 {{expected loop after transformation pragma}} */
+#pragma clang transform unroll
+  pragma_transform(List, Length);
+
+/* expected-error@+1 {{unknown clause name}} */
+#pragma clang transform unroll unknown_clause
+  for (int i = 0; i < Length; i+=1)
+      List[i] = i;
+
+/* expected-error@+1 {{expected '(' after 'partial'}} */
+#pragma clang transform unroll partial
+  for (int i = 0; i < Length; i+=1)
+      List[i] = i;
+
+/* expected-error@+1 {{expected expression}} */
+#pragma clang transform unroll partial(
+  for (int i = 0; i < Length; i+=1)
+      List[i] = i;
+
+/* expected-error@+1 {{expected '(' after 'partial'}} */
+#pragma clang transform unroll partial)
+  for (int i = 0; i < Length; i+=1)
+      List[i] = i;
+
+/* expected-error@+2 {{expected ')'}} */
+/* expected-note@+1 {{to match this '('}} */
+#pragma clang transform unroll partial(4
+  for (int i = 0; i < Length; i+=1)
+      List[i] = i;
+
+/* expected-error@+1 {{expected expression}} */
+#pragma clang transform unroll partial()
+  for (int i = 0; i < Length; i+=1)
+      List[i] = i;
+
+/* expected-error@+1 {{use of undeclared identifier 'badvalue'}} */
+#pragma clang transform unroll partial(badvalue)
+  for (int i = 0; i < Length; i+=1)
+      List[i] = i;
+
+  {
+/* expected-error@+2 {{expected statement}} */
+#pragma clang transform unroll
+  }
+}
+
+/* expected-error@+1 {{expected unqualified-id}} */
+#pragma clang transform unroll
+int I;
+
+/* expected-error@+1 {{expected unqualified-id}} */
+#pragma clang transform unroll
+void func();
+
+class C1 {
+/* expected-error@+3 {{this pragma cannot appear in class declaration}} */
+/* expected-error@+2 {{expected member name or ';' after declaration specifiers}} */
+/* expected-error@+1 {{unknown type name 'unroll'}} */
+#pragma clang transform unroll
+};
+
+template<int F>
+void pragma_transform_template_func(int *List, int Length) {
+#pragma clang transform unroll partial(F)
+  for (int i = 0; i < Length; i+=1)
+      List[i] = i;
+}
+
+template<int F>
+class C2 {
+  void pragma_transform_template_class(int *List, int Length) {
+#pragma clang transform unroll partial(F)
+    for (int i = 0; i < Length; i+=1)
+        List[i] = i;
+  }
+};
Index: clang/lib/Sema/SemaTransform.cpp
===================================================================
--- /dev/null
+++ clang/lib/Sema/SemaTransform.cpp
@@ -0,0 +1,49 @@
+//===---- SemaTransform.h ------------------------------------- -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Semantic analysis for code transformations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/StmtTransform.h"
+#include "clang/Basic/Transform.h"
+#include "clang/Sema/Sema.h"
+#include "clang/Sema/SemaDiagnostic.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringMap.h"
+
+using namespace clang;
+
+StmtResult
+Sema::ActOnLoopTransformDirective(Transform::Kind Kind,
+                                  llvm::ArrayRef<TransformClause *> Clauses,
+                                  Stmt *AStmt, SourceRange Loc) {
+  // TOOD: implement
+  return StmtError();
+}
+
+TransformClause *Sema::ActOnFullClause(SourceRange Loc) {
+  // TOOD: implement
+  return nullptr;
+}
+
+TransformClause *Sema::ActOnPartialClause(SourceRange Loc, Expr *Factor) {
+  // TOOD: implement
+  return nullptr;
+}
+
+TransformClause *Sema::ActOnWidthClause(SourceRange Loc, Expr *Width) {
+  // TOOD: implement
+  return nullptr;
+}
+
+TransformClause *Sema::ActOnFactorClause(SourceRange Loc, Expr *Factor) {
+  // TOOD: implement
+  return nullptr;
+}
Index: clang/lib/Sema/CMakeLists.txt
===================================================================
--- clang/lib/Sema/CMakeLists.txt
+++ clang/lib/Sema/CMakeLists.txt
@@ -62,6 +62,7 @@
   SemaTemplateInstantiate.cpp
   SemaTemplateInstantiateDecl.cpp
   SemaTemplateVariadic.cpp
+  SemaTransform.cpp
   SemaType.cpp
   TypeLocBuilder.cpp
 
Index: clang/lib/Parse/ParseTransform.cpp
===================================================================
--- /dev/null
+++ clang/lib/Parse/ParseTransform.cpp
@@ -0,0 +1,144 @@
+//===---- ParseTransform.h -------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Parse #pragma clang transform ...
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/StmtTransform.h"
+#include "clang/Parse/Parser.h"
+#include "clang/Parse/RAIIObjectsForParser.h"
+
+using namespace clang;
+
+Transform::Kind
+Parser::tryParsePragmaTransform(SourceLocation BeginLoc,
+                                ParsedStmtContext StmtCtx,
+                                SmallVectorImpl<TransformClause *> &Clauses) {
+  // ... Tok=<transform> | <...> tok::annot_pragma_transform_end ...
+  if (Tok.isNot(tok::identifier)) {
+    Diag(Tok, diag::err_pragma_transform_expected_directive);
+    return Transform::UnknownKind;
+  }
+  std::string DirectiveStr = PP.getSpelling(Tok);
+  Transform::Kind DirectiveKind =
+      Transform::getTransformDirectiveKind(DirectiveStr);
+  ConsumeToken();
+
+  switch (DirectiveKind) {
+  case Transform::LoopUnrollingKind:
+  case Transform::LoopUnrollAndJamKind:
+  case Transform::LoopDistributionKind:
+  case Transform::LoopVectorizationKind:
+  case Transform::LoopInterleavingKind:
+    break;
+  default:
+    Diag(Tok, diag::err_pragma_transform_unknown_directive);
+    return Transform::UnknownKind;
+  }
+
+  while (true) {
+    TransformClauseResult Clause = ParseTransformClause(DirectiveKind);
+    if (Clause.isInvalid())
+      return Transform::UnknownKind;
+    if (!Clause.isUsable())
+      break;
+
+    Clauses.push_back(Clause.get());
+  }
+
+  assert(Tok.is(tok::annot_pragma_transform_end));
+  return DirectiveKind;
+}
+
+StmtResult Parser::ParsePragmaTransform(ParsedStmtContext StmtCtx) {
+  assert(Tok.is(tok::annot_pragma_transform) && "Not a transform directive!");
+
+  // ... Tok=annot_pragma_transform | <trans> <...> annot_pragma_transform_end
+  // ...
+  SourceLocation BeginLoc = ConsumeAnnotationToken();
+
+  ParenBraceBracketBalancer BalancerRAIIObj(*this);
+
+  SmallVector<TransformClause *, 8> DirectiveClauses;
+  Transform::Kind DirectiveKind =
+      tryParsePragmaTransform(BeginLoc, StmtCtx, DirectiveClauses);
+  if (DirectiveKind == Transform::UnknownKind) {
+    SkipUntil(tok::annot_pragma_transform_end);
+    return StmtError();
+  }
+
+  assert(Tok.is(tok::annot_pragma_transform_end));
+  SourceLocation EndLoc = ConsumeAnnotationToken();
+
+  SourceLocation PreStmtLoc = Tok.getLocation();
+  StmtResult AssociatedStmt = ParseStatement();
+  if (AssociatedStmt.isInvalid())
+    return AssociatedStmt;
+  if (!getAssociatedLoop(AssociatedStmt.get()))
+    return StmtError(
+        Diag(PreStmtLoc, diag::err_pragma_transform_expected_loop));
+
+  return Actions.ActOnLoopTransformDirective(
+      DirectiveKind, DirectiveClauses, AssociatedStmt.get(), {BeginLoc, EndLoc});
+}
+
+Parser::TransformClauseResult
+Parser::ParseTransformClause(Transform::Kind TransformKind) {
+  // No more clauses
+  if (Tok.is(tok::annot_pragma_transform_end))
+    return ClauseEmpty();
+
+  SourceLocation StartLoc = Tok.getLocation();
+  if (Tok.isNot(tok::identifier))
+    return ClauseError(Diag(Tok, diag::err_pragma_transform_expected_clause));
+  std::string ClauseKeyword = PP.getSpelling(Tok);
+  ConsumeToken();
+  TransformClause::Kind Kind =
+      TransformClause::getClauseKind(TransformKind, ClauseKeyword);
+
+  switch (Kind) {
+  case TransformClause::UnknownKind:
+    return ClauseError(Diag(Tok, diag::err_pragma_transform_unknown_clause));
+
+    // Clauses without arguments.
+  case TransformClause::FullKind:
+    return Actions.ActOnFullClause(SourceRange{StartLoc, StartLoc});
+
+    // Clauses with integer argument.
+  case TransformClause::PartialKind:
+  case TransformClause::WidthKind:
+  case TransformClause::FactorKind: {
+    BalancedDelimiterTracker T(*this, tok::l_paren,
+                               tok::annot_pragma_transform_end);
+    if (T.expectAndConsume(diag::err_expected_lparen_after,
+                           ClauseKeyword.data()))
+      return ClauseError();
+
+    ExprResult Expr = ParseConstantExpression();
+    if (Expr.isInvalid())
+      return ClauseError();
+
+    if (T.consumeClose())
+      return ClauseError();
+    SourceLocation EndLoc = T.getCloseLocation();
+    SourceRange Range{StartLoc, EndLoc};
+    switch (Kind) {
+    case TransformClause::PartialKind:
+      return Actions.ActOnPartialClause(Range, Expr.get());
+    case TransformClause::WidthKind:
+      return Actions.ActOnWidthClause(Range, Expr.get());
+    case TransformClause::FactorKind:
+      return Actions.ActOnFactorClause(Range, Expr.get());
+    default:
+      llvm_unreachable("Unhandled clause");
+    }
+  }
+  }
+  llvm_unreachable("Unhandled clause");
+}
Index: clang/lib/Parse/ParseStmt.cpp
===================================================================
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/PrettyDeclStackTrace.h"
+#include "clang/Basic/Transform.h"
 #include "clang/Basic/Attributes.h"
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/Parse/LoopHint.h"
@@ -400,6 +401,10 @@
     ProhibitAttributes(Attrs);
     return ParsePragmaLoopHint(Stmts, StmtCtx, TrailingElseLoc, Attrs);
 
+  case tok::annot_pragma_transform:
+    ProhibitAttributes(Attrs);
+    return ParsePragmaTransform(StmtCtx);
+
   case tok::annot_pragma_dump:
     HandlePragmaDump();
     return StmtEmpty();
Index: clang/lib/Parse/CMakeLists.txt
===================================================================
--- clang/lib/Parse/CMakeLists.txt
+++ clang/lib/Parse/CMakeLists.txt
@@ -19,6 +19,7 @@
   ParseStmtAsm.cpp
   ParseTemplate.cpp
   ParseTentative.cpp
+  ParseTransform.cpp
   Parser.cpp
 
   LINK_LIBS
Index: clang/lib/Basic/Transform.cpp
===================================================================
--- /dev/null
+++ clang/lib/Basic/Transform.cpp
@@ -0,0 +1,49 @@
+//===--- Transform.h - Code transformation classes --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines classes used for code transformations such as
+//  #pragma clang transform ...
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/Transform.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/Casting.h"
+
+using namespace clang;
+
+Transform::Kind Transform ::getTransformDirectiveKind(llvm::StringRef Str) {
+  return llvm::StringSwitch<Transform::Kind>(Str)
+#define TRANSFORM_DIRECTIVE(Keyword, Name)                                     \
+  .Case(#Keyword, Transform::Kind::Name##Kind)
+#include "clang/Basic/TransformKinds.def"
+      .Default(Transform::UnknownKind);
+}
+
+llvm::StringRef Transform ::getTransformDirectiveKeyword(Kind K) {
+  assert(K >= UnknownKind);
+  assert(K <= LastKind);
+  const char *Keywords[LastKind + 1] = {
+      "<<Unknown>>",
+#define TRANSFORM_DIRECTIVE(Keyword, Name) #Keyword,
+#include "clang/Basic/TransformKinds.def"
+  };
+  return Keywords[K];
+}
+
+llvm::StringRef Transform ::getTransformDirectiveName(Kind K) {
+  assert(K >= UnknownKind);
+  assert(K <= LastKind);
+  const char *Keywords[LastKind + 1] = {
+      "<<Unknown>>",
+#define TRANSFORM_DIRECTIVE(Keyword, Name) #Name,
+#include "clang/Basic/TransformKinds.def"
+  };
+  return Keywords[K];
+}
+
Index: clang/lib/Basic/CMakeLists.txt
===================================================================
--- clang/lib/Basic/CMakeLists.txt
+++ clang/lib/Basic/CMakeLists.txt
@@ -87,6 +87,7 @@
   Targets/X86.cpp
   Targets/XCore.cpp
   TokenKinds.cpp
+  Transform.cpp
   Version.cpp
   Warnings.cpp
   XRayInstr.cpp
Index: clang/lib/AST/StmtTransform.cpp
===================================================================
--- /dev/null
+++ clang/lib/AST/StmtTransform.cpp
@@ -0,0 +1,76 @@
+//===--- StmtTransform.h - Code transformation AST nodes --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//  Transformation directive statement and clauses for the AST.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/StmtTransform.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtOpenMP.h"
+
+using namespace clang;
+
+bool TransformClause::isValidForTransform(Transform::Kind TransformKind,
+                                          TransformClause::Kind ClauseKind) {
+  switch (TransformKind) {
+  case clang::Transform::LoopUnrollingKind:
+    return ClauseKind == PartialKind || ClauseKind == FullKind;
+  case clang::Transform::LoopUnrollAndJamKind:
+    return ClauseKind == PartialKind;
+  case clang::Transform::LoopVectorizationKind:
+    return ClauseKind == WidthKind;
+  case clang::Transform::LoopInterleavingKind:
+    return ClauseKind == FactorKind;
+  default:
+    return false;
+  }
+}
+
+TransformClause::Kind
+TransformClause ::getClauseKind(Transform::Kind TransformKind,
+                                llvm::StringRef Str) {
+#define TRANSFORM_CLAUSE(Keyword, Name)                                        \
+  if (isValidForTransform(TransformKind, TransformClause::Kind::Name##Kind) && \
+      Str == #Keyword)                                                         \
+    return TransformClause::Kind::Name##Kind;
+#include "clang/AST/TransformClauseKinds.def"
+  return TransformClause::UnknownKind;
+}
+
+llvm::StringRef
+TransformClause ::getClauseKeyword(TransformClause::Kind ClauseKind) {
+  assert(ClauseKind > UnknownKind);
+  assert(ClauseKind <= LastKind);
+  static const char *ClauseKeyword[LastKind] = {
+#define TRANSFORM_CLAUSE(Keyword, Name) #Keyword,
+#include "clang/AST/TransformClauseKinds.def"
+
+  };
+  return ClauseKeyword[ClauseKind - 1];
+}
+
+const Stmt *clang::getAssociatedLoop(const Stmt *S) {
+  switch (S->getStmtClass()) {
+  case Stmt::ForStmtClass:
+  case Stmt::WhileStmtClass:
+  case Stmt::DoStmtClass:
+  case Stmt::CXXForRangeStmtClass:
+    return S;
+  case Stmt::CapturedStmtClass:
+    return getAssociatedLoop(cast<CapturedStmt>(S)->getCapturedStmt());
+  case Stmt::AttributedStmtClass:
+    return getAssociatedLoop(cast<AttributedStmt>(S)->getSubStmt());
+  default:
+    if (auto LD = dyn_cast<OMPLoopDirective>(S))
+      return getAssociatedLoop(LD->getAssociatedStmt());
+  }
+
+  return nullptr;
+}
Index: clang/lib/AST/CMakeLists.txt
===================================================================
--- clang/lib/AST/CMakeLists.txt
+++ clang/lib/AST/CMakeLists.txt
@@ -98,6 +98,7 @@
   StmtOpenMP.cpp
   StmtPrinter.cpp
   StmtProfile.cpp
+  StmtTransform.cpp
   StmtViz.cpp
   TemplateBase.cpp
   TemplateName.cpp
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -28,6 +28,7 @@
 #include "clang/AST/NSAPI.h"
 #include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/StmtCXX.h"
+#include "clang/AST/StmtTransform.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/AST/TypeOrdering.h"
 #include "clang/Basic/ExpressionTraits.h"
@@ -11630,6 +11631,16 @@
     ConstructorDestructor,
     BuiltinFunction
   };
+
+  StmtResult
+  ActOnLoopTransformDirective(Transform::Kind Kind, 
+                              llvm::ArrayRef<TransformClause *> Clauses,
+                              Stmt *AStmt, SourceRange Loc);
+
+  TransformClause *ActOnFullClause(SourceRange Loc);
+  TransformClause *ActOnPartialClause(SourceRange Loc, Expr *Factor);
+  TransformClause *ActOnWidthClause(SourceRange Loc, Expr *Width);
+  TransformClause *ActOnFactorClause(SourceRange Loc, Expr *Factor);
 };
 
 /// RAII object that enters a new expression evaluation context.
Index: clang/include/clang/Parse/Parser.h
===================================================================
--- clang/include/clang/Parse/Parser.h
+++ clang/include/clang/Parse/Parser.h
@@ -1642,6 +1642,17 @@
     IsTypeCast
   };
 
+  using TransformClauseResult = ActionResult<TransformClause *>;
+  static TransformClauseResult ClauseError() {
+    return TransformClauseResult(true);
+  }
+  static TransformClauseResult ClauseError(const DiagnosticBuilder &) {
+    return ClauseError();
+  }
+  static TransformClauseResult ClauseEmpty() {
+    return TransformClauseResult(false);
+  }
+
   ExprResult ParseExpression(TypeCastState isTypeCast = NotTypeCast);
   ExprResult ParseConstantExpressionInExprEvalContext(
       TypeCastState isTypeCast = NotTypeCast);
@@ -1978,6 +1989,12 @@
                                  SourceLocation *TrailingElseLoc,
                                  ParsedAttributesWithRange &Attrs);
 
+  Transform::Kind
+  tryParsePragmaTransform(SourceLocation BeginLoc, ParsedStmtContext StmtCtx,
+                          SmallVectorImpl<TransformClause *> &Clauses);
+  StmtResult ParsePragmaTransform(ParsedStmtContext StmtCtx);
+  TransformClauseResult ParseTransformClause(Transform::Kind TransformKind);
+
   /// Describes the behavior that should be taken for an __if_exists
   /// block.
   enum IfExistsBehavior {
Index: clang/include/clang/Basic/TransformKinds.def
===================================================================
--- /dev/null
+++ clang/include/clang/Basic/TransformKinds.def
@@ -0,0 +1,22 @@
+
+#ifndef TRANSFORM_DIRECTIVE
+#  define TRANSFORM_DIRECTIVE(Keyword, Name)
+#endif
+#ifndef TRANSFORM_DIRECTIVE_LAST
+#  define TRANSFORM_DIRECTIVE_LAST(Keyword, Name) TRANSFORM_DIRECTIVE(Keyword, Name)
+#endif
+
+// Loop transformations
+TRANSFORM_DIRECTIVE(distribute,LoopDistribution)
+TRANSFORM_DIRECTIVE(vectorize,LoopVectorization)
+TRANSFORM_DIRECTIVE(interleave,LoopInterleaving)
+TRANSFORM_DIRECTIVE(vectorize_interleave,LoopVectorizationInterleaving)
+TRANSFORM_DIRECTIVE(unrollandjam,LoopUnrollAndJam)
+TRANSFORM_DIRECTIVE(unroll,LoopUnrolling)
+TRANSFORM_DIRECTIVE(pipeline,LoopPipelining)
+
+// Assumptions
+TRANSFORM_DIRECTIVE_LAST(assume_parallel,LoopAssumeParallel)
+
+#undef TRANSFORM_DIRECTIVE
+#undef TRANSFORM_DIRECTIVE_LAST
Index: clang/include/clang/Basic/Transform.h
===================================================================
--- /dev/null
+++ clang/include/clang/Basic/Transform.h
@@ -0,0 +1,39 @@
+//===--- Transform.h - Code transformation classes --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines classes used for code transformations such as
+//  #pragma clang transform ...
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_TRANSFORM_H
+#define LLVM_CLANG_BASIC_TRANSFORM_H
+
+#include "clang/AST/Stmt.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+
+class Transform {
+public:
+  enum Kind {
+    UnknownKind,
+#define TRANSFORM_DIRECTIVE(Keyword, Name) Name##Kind,
+#define TRANSFORM_DIRECTIVE_LAST(Keyword, Name)                                \
+  TRANSFORM_DIRECTIVE(Keyword, Name)                                           \
+  LastKind = Name##Kind
+#include "TransformKinds.def"
+  };
+
+  static Kind getTransformDirectiveKind(llvm::StringRef Str);
+  static llvm::StringRef getTransformDirectiveKeyword(Kind K);
+  static llvm::StringRef getTransformDirectiveName(Kind K);
+};
+
+} // namespace clang
+#endif /* LLVM_CLANG_BASIC_TRANSFORM_H */
Index: clang/include/clang/Basic/DiagnosticParseKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticParseKinds.td
+++ clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1233,6 +1233,18 @@
   "vectorize_width, interleave, interleave_count, unroll, unroll_count, "
   "pipeline, pipeline_initiation_interval, vectorize_predicate, or distribute">;
 
+// Pragma transform support.
+def err_pragma_transform_expected_directive : Error<
+  "expected a transformation name">;
+def err_pragma_transform_unknown_directive : Error<
+  "unknown transformation">;
+def err_pragma_transform_expected_loop : Error<
+  "expected loop after transformation pragma">;
+def err_pragma_transform_expected_clause : Error<
+  "expected a clause name">;
+def err_pragma_transform_unknown_clause : Error<
+  "unknown clause name">;
+
 def err_pragma_fp_invalid_option : Error<
   "%select{invalid|missing}0 option%select{ %1|}0; expected contract">;
 def err_pragma_fp_invalid_argument : Error<
Index: clang/include/clang/Basic/DiagnosticGroups.td
===================================================================
--- clang/include/clang/Basic/DiagnosticGroups.td
+++ clang/include/clang/Basic/DiagnosticGroups.td
@@ -1114,3 +1114,5 @@
 def CTADMaybeUnsupported : DiagGroup<"ctad-maybe-unsupported">;
 
 def FortifySource : DiagGroup<"fortify-source">;
+
+def ClangTransform : DiagGroup<"pragma-transform">;
Index: clang/include/clang/AST/TransformClauseKinds.def
===================================================================
--- /dev/null
+++ clang/include/clang/AST/TransformClauseKinds.def
@@ -0,0 +1,16 @@
+
+#ifndef TRANSFORM_CLAUSE
+#  define TRANSFORM_CLAUSE(Keyword, Name)
+#endif
+#ifndef TRANSFORM_CLAUSE_LAST
+#  define TRANSFORM_CLAUSE_LAST(Keyword, Name)  TRANSFORM_CLAUSE(Keyword, Name)
+#endif
+
+TRANSFORM_CLAUSE(full,Full)
+TRANSFORM_CLAUSE(partial,Partial)
+
+TRANSFORM_CLAUSE(width,Width)
+TRANSFORM_CLAUSE_LAST(factor,Factor)
+
+#undef TRANSFORM_CLAUSE
+#undef TRANSFORM_CLAUSE_LAST
Index: clang/include/clang/AST/StmtTransform.h
===================================================================
--- /dev/null
+++ clang/include/clang/AST/StmtTransform.h
@@ -0,0 +1,52 @@
+//===--- StmtTransform.h - Code transformation AST nodes --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+//  Transformation directive statement and clauses for the AST.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_STMTTRANSFROM_H
+#define LLVM_CLANG_AST_STMTTRANSFROM_H
+
+#include "clang/AST/Stmt.h"
+#include "llvm/Support/raw_ostream.h"
+#include "clang/Basic/Transform.h"
+
+namespace clang {
+
+/// Represents a clause of a \p TransformExecutableDirective.
+class TransformClause {
+public:
+  enum Kind {
+    UnknownKind,
+#define TRANSFORM_CLAUSE(Keyword, Name) Name##Kind,
+#define TRANSFORM_CLAUSE_LAST(Keyword, Name) Name##Kind, LastKind = Name##Kind
+#include "clang/AST/TransformClauseKinds.def"
+  };
+
+  static bool isValidForTransform(Transform::Kind TransformKind,
+                                  TransformClause::Kind ClauseKind);
+  static Kind getClauseKind(Transform::Kind TransformKind, llvm::StringRef Str);
+  static llvm::StringRef getClauseKeyword(TransformClause::Kind ClauseKind);
+
+  // TODO: implement
+};
+
+/// Represents
+///
+///   #pragma clang transform
+///
+/// in the AST.
+class TransformExecutableDirective final {
+  // TODO: implement
+};
+
+const Stmt *getAssociatedLoop(const Stmt *S);
+} // namespace clang
+
+#endif /* LLVM_CLANG_AST_STMTTRANSFROM_H */
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D69089: [Parser] #pr... Michael Kruse via Phabricator via cfe-commits

Reply via email to