r209816 - Parsing/Sema for OMPAlignedClause.

Alexander Musman alexander.musman at gmail.com
Thu May 29 07:36:26 PDT 2014


Author: amusman
Date: Thu May 29 09:36:25 2014
New Revision: 209816

URL: http://llvm.org/viewvc/llvm-project?rev=209816&view=rev
Log:
Parsing/Sema for OMPAlignedClause.


Added:
    cfe/trunk/test/OpenMP/simd_aligned_messages.cpp
Modified:
    cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h
    cfe/trunk/include/clang/AST/OpenMPClause.h
    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Basic/OpenMPKinds.def
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/AST/Stmt.cpp
    cfe/trunk/lib/AST/StmtPrinter.cpp
    cfe/trunk/lib/AST/StmtProfile.cpp
    cfe/trunk/lib/Basic/OpenMPKinds.cpp
    cfe/trunk/lib/Parse/ParseOpenMP.cpp
    cfe/trunk/lib/Sema/SemaOpenMP.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
    cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
    cfe/trunk/test/OpenMP/simd_ast_print.cpp
    cfe/trunk/test/OpenMP/simd_misc_messages.c
    cfe/trunk/tools/libclang/CIndex.cpp

Modified: cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h?rev=209816&r1=209815&r2=209816&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h Thu May 29 09:36:25 2014
@@ -2367,6 +2367,13 @@ bool RecursiveASTVisitor<Derived>::Visit
 }
 
 template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPAlignedClause(OMPAlignedClause *C) {
+  VisitOMPClauseList(C);
+  TraverseStmt(C->getAlignment());
+  return true;
+}
+
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
   VisitOMPClauseList(C);
   return true;

Modified: cfe/trunk/include/clang/AST/OpenMPClause.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OpenMPClause.h?rev=209816&r1=209815&r2=209816&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/OpenMPClause.h (original)
+++ cfe/trunk/include/clang/AST/OpenMPClause.h Thu May 29 09:36:25 2014
@@ -764,6 +764,91 @@ public:
   }
 };
 
+/// \brief This represents clause 'aligned' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp simd aligned(a,b : 8)
+/// \endcode
+/// In this example directive '#pragma omp simd' has clause 'aligned'
+/// with variables 'a', 'b' and alignment '8'.
+///
+class OMPAlignedClause : public OMPVarListClause<OMPAlignedClause> {
+  friend class OMPClauseReader;
+  /// \brief Location of ':'.
+  SourceLocation ColonLoc;
+
+  /// \brief Sets the alignment for clause.
+  void setAlignment(Expr *A) { *varlist_end() = A; }
+
+  /// \brief Build 'aligned' clause with given number of variables \a NumVars.
+  ///
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param ColonLoc Location of ':'.
+  /// \param EndLoc Ending location of the clause.
+  /// \param NumVars Number of variables.
+  ///
+  OMPAlignedClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+                   SourceLocation ColonLoc, SourceLocation EndLoc,
+                   unsigned NumVars)
+      : OMPVarListClause<OMPAlignedClause>(OMPC_aligned, StartLoc, LParenLoc,
+                                           EndLoc, NumVars),
+        ColonLoc(ColonLoc) {}
+
+  /// \brief Build an empty clause.
+  ///
+  /// \param NumVars Number of variables.
+  ///
+  explicit OMPAlignedClause(unsigned NumVars)
+      : OMPVarListClause<OMPAlignedClause>(OMPC_aligned, SourceLocation(),
+                                           SourceLocation(), SourceLocation(),
+                                           NumVars),
+        ColonLoc(SourceLocation()) {}
+
+public:
+  /// \brief Creates clause with a list of variables \a VL and alignment \a A.
+  ///
+  /// \param C AST Context.
+  /// \param StartLoc Starting location of the clause.
+  /// \param LParenLoc Location of '('.
+  /// \param ColonLoc Location of ':'.
+  /// \param EndLoc Ending location of the clause.
+  /// \param VL List of references to the variables.
+  /// \param A Alignment.
+  static OMPAlignedClause *Create(const ASTContext &C, SourceLocation StartLoc,
+                                  SourceLocation LParenLoc,
+                                  SourceLocation ColonLoc,
+                                  SourceLocation EndLoc, ArrayRef<Expr *> VL,
+                                  Expr *A);
+
+  /// \brief Creates an empty clause with the place for \a NumVars variables.
+  ///
+  /// \param C AST context.
+  /// \param NumVars Number of variables.
+  ///
+  static OMPAlignedClause *CreateEmpty(const ASTContext &C, unsigned NumVars);
+
+  /// \brief Sets the location of ':'.
+  void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
+  /// \brief Returns the location of ':'.
+  SourceLocation getColonLoc() const { return ColonLoc; }
+
+  /// \brief Returns alignment.
+  Expr *getAlignment() { return *varlist_end(); }
+  /// \brief Returns alignment.
+  const Expr *getAlignment() const { return *varlist_end(); }
+
+  StmtRange children() {
+    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+                     reinterpret_cast<Stmt **>(varlist_end() + 1));
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == OMPC_aligned;
+  }
+};
+
 /// \brief This represents clause 'copyin' in the '#pragma omp ...' directives.
 ///
 /// \code

Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=209816&r1=209815&r2=209816&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Thu May 29 09:36:25 2014
@@ -2388,6 +2388,13 @@ bool RecursiveASTVisitor<Derived>::Visit
 }
 
 template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPAlignedClause(OMPAlignedClause *C) {
+  VisitOMPClauseList(C);
+  TraverseStmt(C->getAlignment());
+  return true;
+}
+
+template <typename Derived>
 bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
   VisitOMPClauseList(C);
   return true;

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=209816&r1=209815&r2=209816&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu May 29 09:36:25 2014
@@ -6954,6 +6954,12 @@ def err_omp_linear_expected_int_or_ptr :
 def warn_omp_linear_step_zero : Warning<
   "zero linear step (%0 %select{|and other variables in clause }1should probably be const)">,
   InGroup<OpenMPClauses>;
+def err_omp_aligned_expected_array_or_ptr : Error<
+  "argument of aligned clause should be array"
+  "%select{ or pointer|, pointer, reference to array or reference to pointer}1"
+  ", not %0">;
+def err_omp_aligned_twice : Error<
+  "a variable cannot appear in more than one aligned clause">;
 def err_omp_local_var_in_threadprivate_init : Error<
   "variable with local storage in initial value of threadprivate variable">;
 } // end of OpenMP category

Modified: cfe/trunk/include/clang/Basic/OpenMPKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OpenMPKinds.def?rev=209816&r1=209815&r2=209816&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/OpenMPKinds.def (original)
+++ cfe/trunk/include/clang/Basic/OpenMPKinds.def Thu May 29 09:36:25 2014
@@ -47,6 +47,7 @@ OPENMP_CLAUSE(private, OMPPrivateClause)
 OPENMP_CLAUSE(firstprivate, OMPFirstprivateClause)
 OPENMP_CLAUSE(shared,  OMPSharedClause)
 OPENMP_CLAUSE(linear,  OMPLinearClause)
+OPENMP_CLAUSE(aligned, OMPAlignedClause)
 OPENMP_CLAUSE(copyin,  OMPCopyinClause)
 OPENMP_CLAUSE(proc_bind, OMPProcBindClause)
 
@@ -63,6 +64,7 @@ OPENMP_PARALLEL_CLAUSE(copyin)
 // FIXME: more clauses allowed for directive 'omp simd'.
 OPENMP_SIMD_CLAUSE(private)
 OPENMP_SIMD_CLAUSE(linear)
+OPENMP_SIMD_CLAUSE(aligned)
 OPENMP_SIMD_CLAUSE(safelen)
 OPENMP_SIMD_CLAUSE(collapse)
 

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=209816&r1=209815&r2=209816&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu May 29 09:36:25 2014
@@ -7383,6 +7383,13 @@ public:
                                      SourceLocation LParenLoc,
                                      SourceLocation ColonLoc,
                                      SourceLocation EndLoc);
+  /// \brief Called on well-formed 'aligned' clause.
+  OMPClause *ActOnOpenMPAlignedClause(ArrayRef<Expr *> VarList,
+                                      Expr *Alignment,
+                                      SourceLocation StartLoc,
+                                      SourceLocation LParenLoc,
+                                      SourceLocation ColonLoc,
+                                      SourceLocation EndLoc);
   /// \brief Called on well-formed 'copyin' clause.
   OMPClause *ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
                                      SourceLocation StartLoc,

Modified: cfe/trunk/lib/AST/Stmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=209816&r1=209815&r2=209816&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Stmt.cpp (original)
+++ cfe/trunk/lib/AST/Stmt.cpp Thu May 29 09:36:25 2014
@@ -1214,6 +1214,28 @@ OMPLinearClause *OMPLinearClause::Create
   return new (Mem) OMPLinearClause(NumVars);
 }
 
+OMPAlignedClause *
+OMPAlignedClause::Create(const ASTContext &C, SourceLocation StartLoc,
+                         SourceLocation LParenLoc, SourceLocation ColonLoc,
+                         SourceLocation EndLoc, ArrayRef<Expr *> VL, Expr *A) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPAlignedClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * (VL.size() + 1));
+  OMPAlignedClause *Clause = new (Mem)
+      OMPAlignedClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size());
+  Clause->setVarRefs(VL);
+  Clause->setAlignment(A);
+  return Clause;
+}
+
+OMPAlignedClause *OMPAlignedClause::CreateEmpty(const ASTContext &C,
+                                                unsigned NumVars) {
+  void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPAlignedClause),
+                                                  llvm::alignOf<Expr *>()) +
+                         sizeof(Expr *) * (NumVars + 1));
+  return new (Mem) OMPAlignedClause(NumVars);
+}
+
 OMPCopyinClause *OMPCopyinClause::Create(const ASTContext &C,
                                          SourceLocation StartLoc,
                                          SourceLocation LParenLoc,

Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=209816&r1=209815&r2=209816&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Thu May 29 09:36:25 2014
@@ -677,6 +677,18 @@ void OMPClausePrinter::VisitOMPLinearCla
   }
 }
 
+void OMPClausePrinter::VisitOMPAlignedClause(OMPAlignedClause *Node) {
+  if (!Node->varlist_empty()) {
+    OS << "aligned";
+    VisitOMPClauseList(Node, '(');
+    if (Node->getAlignment() != nullptr) {
+      OS << ": ";
+      Node->getAlignment()->printPretty(OS, nullptr, Policy, 0);
+    }
+    OS << ")";
+  }
+}
+
 void OMPClausePrinter::VisitOMPCopyinClause(OMPCopyinClause *Node) {
   if (!Node->varlist_empty()) {
     OS << "copyin";

Modified: cfe/trunk/lib/AST/StmtProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=209816&r1=209815&r2=209816&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtProfile.cpp (original)
+++ cfe/trunk/lib/AST/StmtProfile.cpp Thu May 29 09:36:25 2014
@@ -308,6 +308,10 @@ void OMPClauseProfiler::VisitOMPLinearCl
   VisitOMPClauseList(C);
   Profiler->VisitStmt(C->getStep());
 }
+void OMPClauseProfiler::VisitOMPAlignedClause(const OMPAlignedClause *C) {
+  VisitOMPClauseList(C);
+  Profiler->VisitStmt(C->getAlignment());
+}
 void OMPClauseProfiler::VisitOMPCopyinClause(const OMPCopyinClause *C) {
   VisitOMPClauseList(C);
 }

Modified: cfe/trunk/lib/Basic/OpenMPKinds.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/OpenMPKinds.cpp?rev=209816&r1=209815&r2=209816&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/OpenMPKinds.cpp (original)
+++ cfe/trunk/lib/Basic/OpenMPKinds.cpp Thu May 29 09:36:25 2014
@@ -88,6 +88,7 @@ unsigned clang::getOpenMPSimpleClauseTyp
   case OMPC_firstprivate:
   case OMPC_shared:
   case OMPC_linear:
+  case OMPC_aligned:
   case OMPC_copyin:
     break;
   }
@@ -125,6 +126,7 @@ const char *clang::getOpenMPSimpleClause
   case OMPC_firstprivate:
   case OMPC_shared:
   case OMPC_linear:
+  case OMPC_aligned:
   case OMPC_copyin:
     break;
   }

Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=209816&r1=209815&r2=209816&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original)
+++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Thu May 29 09:36:25 2014
@@ -255,7 +255,7 @@ bool Parser::ParseOpenMPSimpleVarList(Op
 ///    clause:
 ///       if-clause | num_threads-clause | safelen-clause | default-clause |
 ///       private-clause | firstprivate-clause | shared-clause | linear-clause |
-///       collapse-clause
+///       aligned-clause | collapse-clause
 ///
 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
                                      OpenMPClauseKind CKind, bool FirstClause) {
@@ -304,6 +304,7 @@ OMPClause *Parser::ParseOpenMPClause(Ope
   case OMPC_firstprivate:
   case OMPC_shared:
   case OMPC_linear:
+  case OMPC_aligned:
   case OMPC_copyin:
     Clause = ParseOpenMPVarListClause(CKind);
     break;
@@ -400,6 +401,8 @@ OMPClause *Parser::ParseOpenMPSimpleClau
 ///       'shared' '(' list ')'
 ///    linear-clause:
 ///       'linear' '(' list [ ':' linear-step ] ')'
+///    aligned-clause:
+///       'aligned' '(' list [ ':' alignment ] ')'
 ///
 OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
   SourceLocation Loc = Tok.getLocation();
@@ -413,7 +416,7 @@ OMPClause *Parser::ParseOpenMPVarListCla
 
   SmallVector<Expr *, 5> Vars;
   bool IsComma = true;
-  const bool MayHaveTail = (Kind == OMPC_linear);
+  const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
   while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
                      Tok.isNot(tok::annot_pragma_openmp_end))) {
     ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
@@ -435,7 +438,7 @@ OMPClause *Parser::ParseOpenMPVarListCla
       Diag(Tok, diag::err_omp_expected_punc) << getOpenMPClauseName(Kind);
   }
 
-  // Parse ':' linear-step
+  // Parse ':' linear-step (or ':' alignment).
   Expr *TailExpr = nullptr;
   const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
   if (MustHaveTail) {

Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=209816&r1=209815&r2=209816&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Thu May 29 09:36:25 2014
@@ -57,20 +57,23 @@ private:
     DeclRefExpr *RefExpr;
   };
   typedef llvm::SmallDenseMap<VarDecl *, DSAInfo, 64> DeclSAMapTy;
+  typedef llvm::SmallDenseMap<VarDecl *, DeclRefExpr *, 64> AlignedMapTy;
 
   struct SharingMapTy {
     DeclSAMapTy SharingMap;
+    AlignedMapTy AlignedMap;
     DefaultDataSharingAttributes DefaultAttr;
     OpenMPDirectiveKind Directive;
     DeclarationNameInfo DirectiveName;
     Scope *CurScope;
     SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
                  Scope *CurScope)
-        : SharingMap(), DefaultAttr(DSA_unspecified), Directive(DKind),
-          DirectiveName(std::move(Name)), CurScope(CurScope) {}
+        : SharingMap(), AlignedMap(), DefaultAttr(DSA_unspecified),
+          Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope) {
+    }
     SharingMapTy()
-        : SharingMap(), DefaultAttr(DSA_unspecified), Directive(OMPD_unknown),
-          DirectiveName(), CurScope(nullptr) {}
+        : SharingMap(), AlignedMap(), DefaultAttr(DSA_unspecified),
+          Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr) {}
   };
 
   typedef SmallVector<SharingMapTy, 64> StackTy;
@@ -99,6 +102,11 @@ public:
     Stack.pop_back();
   }
 
+  /// \brief If 'aligned' declaration for given variable \a D was not seen yet,
+  /// add it and return NULL; otherwise return previous occurence's expression
+  /// for diagnostics.
+  DeclRefExpr *addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE);
+
   /// \brief Adds explicit data sharing attribute to the specified declaration.
   void addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A);
 
@@ -242,6 +250,20 @@ DSAStackTy::DSAVarData DSAStackTy::getDS
   return getDSA(std::next(Iter), D);
 }
 
+DeclRefExpr *DSAStackTy::addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE) {
+  assert(Stack.size() > 1 && "Data sharing attributes stack is empty");
+  auto It = Stack.back().AlignedMap.find(D);
+  if (It == Stack.back().AlignedMap.end()) {
+    assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
+    Stack.back().AlignedMap[D] = NewDE;
+    return nullptr;
+  } else {
+    assert(It->second && "Unexpected nullptr expr in the aligned map");
+    return It->second;
+  }
+  return nullptr;
+}
+
 void DSAStackTy::addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A) {
   if (A == OMPC_threadprivate) {
     Stack[0].SharingMap[D].Attributes = A;
@@ -855,6 +877,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprCl
   case OMPC_firstprivate:
   case OMPC_shared:
   case OMPC_linear:
+  case OMPC_aligned:
   case OMPC_copyin:
   case OMPC_threadprivate:
   case OMPC_unknown:
@@ -1025,6 +1048,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause
   case OMPC_firstprivate:
   case OMPC_shared:
   case OMPC_linear:
+  case OMPC_aligned:
   case OMPC_copyin:
   case OMPC_threadprivate:
   case OMPC_unknown:
@@ -1128,6 +1152,10 @@ Sema::ActOnOpenMPVarListClause(OpenMPCla
     Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
                                   ColonLoc, EndLoc);
     break;
+  case OMPC_aligned:
+    Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
+                                   ColonLoc, EndLoc);
+    break;
   case OMPC_copyin:
     Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
     break;
@@ -1641,6 +1669,81 @@ OMPClause *Sema::ActOnOpenMPLinearClause
                                  Vars, StepExpr);
 }
 
+OMPClause *Sema::ActOnOpenMPAlignedClause(
+    ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
+    SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
+
+  SmallVector<Expr *, 8> Vars;
+  for (auto &RefExpr : VarList) {
+    assert(RefExpr && "NULL expr in OpenMP aligned clause.");
+    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
+      // It will be analyzed later.
+      Vars.push_back(RefExpr);
+      continue;
+    }
+
+    SourceLocation ELoc = RefExpr->getExprLoc();
+    // OpenMP [2.1, C/C++]
+    //  A list item is a variable name.
+    DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
+    if (!DE || !isa<VarDecl>(DE->getDecl())) {
+      Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange();
+      continue;
+    }
+
+    VarDecl *VD = cast<VarDecl>(DE->getDecl());
+
+    // OpenMP  [2.8.1, simd construct, Restrictions]
+    // The type of list items appearing in the aligned clause must be
+    // array, pointer, reference to array, or reference to pointer.
+    QualType QType = DE->getType()
+                         .getNonReferenceType()
+                         .getUnqualifiedType()
+                         .getCanonicalType();
+    const Type *Ty = QType.getTypePtrOrNull();
+    if (!Ty || (!Ty->isDependentType() && !Ty->isArrayType() &&
+                !Ty->isPointerType())) {
+      Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
+          << QType << getLangOpts().CPlusPlus << RefExpr->getSourceRange();
+      bool IsDecl =
+          VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
+      Diag(VD->getLocation(),
+           IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+          << VD;
+      continue;
+    }
+
+    // OpenMP  [2.8.1, simd construct, Restrictions]
+    // A list-item cannot appear in more than one aligned clause.
+    if (DeclRefExpr *PrevRef = DSAStack->addUniqueAligned(VD, DE)) {
+      Diag(ELoc, diag::err_omp_aligned_twice) << RefExpr->getSourceRange();
+      Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
+          << getOpenMPClauseName(OMPC_aligned);
+      continue;
+    }
+
+    Vars.push_back(DE);
+  }
+
+  // OpenMP [2.8.1, simd construct, Description]
+  // The parameter of the aligned clause, alignment, must be a constant
+  // positive integer expression.
+  // If no optional parameter is specified, implementation-defined default
+  // alignments for SIMD instructions on the target platforms are assumed.
+  if (Alignment != nullptr) {
+    ExprResult AlignResult =
+        VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
+    if (AlignResult.isInvalid())
+      return nullptr;
+    Alignment = AlignResult.get();
+  }
+  if (Vars.empty())
+    return nullptr;
+
+  return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
+                                  EndLoc, Vars, Alignment);
+}
+
 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
                                          SourceLocation StartLoc,
                                          SourceLocation LParenLoc,

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=209816&r1=209815&r2=209816&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Thu May 29 09:36:25 2014
@@ -1419,6 +1419,19 @@ public:
                                              ColonLoc, EndLoc);
   }
 
+  /// \brief Build a new OpenMP 'aligned' clause.
+  ///
+  /// By default, performs semantic analysis to build the new statement.
+  /// Subclasses may override this routine to provide different behavior.
+  OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,
+                                     SourceLocation StartLoc,
+                                     SourceLocation LParenLoc,
+                                     SourceLocation ColonLoc,
+                                     SourceLocation EndLoc) {
+    return getSema().ActOnOpenMPAlignedClause(VarList, Alignment, StartLoc,
+                                              LParenLoc, ColonLoc, EndLoc);
+  }
+
   /// \brief Build a new OpenMP 'copyin' clause.
   ///
   /// By default, performs semantic analysis to build the new statement.
@@ -6507,6 +6520,25 @@ TreeTransform<Derived>::TransformOMPLine
 }
 
 template<typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
+  llvm::SmallVector<Expr *, 16> Vars;
+  Vars.reserve(C->varlist_size());
+  for (auto *VE : C->varlists()) {
+    ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
+    if (EVar.isInvalid())
+      return nullptr;
+    Vars.push_back(EVar.get());
+  }
+  ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
+  if (Alignment.isInvalid())
+    return nullptr;
+  return getDerived().RebuildOMPAlignedClause(
+      Vars, Alignment.get(), C->getLocStart(), C->getLParenLoc(),
+      C->getColonLoc(), C->getLocEnd());
+}
+
+template<typename Derived>
 OMPClause *
 TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
   llvm::SmallVector<Expr *, 16> Vars;

Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=209816&r1=209815&r2=209816&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Thu May 29 09:36:25 2014
@@ -1703,6 +1703,9 @@ OMPClause *OMPClauseReader::readClause()
   case OMPC_linear:
     C = OMPLinearClause::CreateEmpty(Context, Record[Idx++]);
     break;
+  case OMPC_aligned:
+    C = OMPAlignedClause::CreateEmpty(Context, Record[Idx++]);
+    break;
   case OMPC_copyin:
     C = OMPCopyinClause::CreateEmpty(Context, Record[Idx++]);
     break;
@@ -1790,6 +1793,18 @@ void OMPClauseReader::VisitOMPLinearClau
   C->setStep(Reader->Reader.ReadSubExpr());
 }
 
+void OMPClauseReader::VisitOMPAlignedClause(OMPAlignedClause *C) {
+  C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
+  C->setColonLoc(Reader->ReadSourceLocation(Record, Idx));
+  unsigned NumVars = C->varlist_size();
+  SmallVector<Expr *, 16> Vars;
+  Vars.reserve(NumVars);
+  for (unsigned i = 0; i != NumVars; ++i)
+    Vars.push_back(Reader->Reader.ReadSubExpr());
+  C->setVarRefs(Vars);
+  C->setAlignment(Reader->Reader.ReadSubExpr());
+}
+
 void OMPClauseReader::VisitOMPCopyinClause(OMPCopyinClause *C) {
   C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
   unsigned NumVars = C->varlist_size();

Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=209816&r1=209815&r2=209816&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Thu May 29 09:36:25 2014
@@ -1737,6 +1737,15 @@ void OMPClauseWriter::VisitOMPLinearClau
   Writer->Writer.AddStmt(C->getStep());
 }
 
+void OMPClauseWriter::VisitOMPAlignedClause(OMPAlignedClause *C) {
+  Record.push_back(C->varlist_size());
+  Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
+  Writer->Writer.AddSourceLocation(C->getColonLoc(), Record);
+  for (auto *VE : C->varlists())
+    Writer->Writer.AddStmt(VE);
+  Writer->Writer.AddStmt(C->getAlignment());
+}
+
 void OMPClauseWriter::VisitOMPCopyinClause(OMPCopyinClause *C) {
   Record.push_back(C->varlist_size());
   Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);

Added: cfe/trunk/test/OpenMP/simd_aligned_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/simd_aligned_messages.cpp?rev=209816&view=auto
==============================================================================
--- cfe/trunk/test/OpenMP/simd_aligned_messages.cpp (added)
+++ cfe/trunk/test/OpenMP/simd_aligned_messages.cpp Thu May 29 09:36:25 2014
@@ -0,0 +1,200 @@
+// RUN: %clang_cc1 -x c++ -std=c++11 -verify -fopenmp=libiomp5 %s
+
+struct B {
+  static int ib[20]; // expected-note 0 {{'B::ib' declared here}}
+  static constexpr int bfoo() { return 8; }
+};
+namespace X {
+  B x; // expected-note {{'x' defined here}}
+};
+constexpr int bfoo() { return 4; }
+
+int **z;
+const int C1 = 1;
+const int C2 = 2;
+void test_aligned_colons(int *&rp)
+{
+  int *B = 0;
+  #pragma omp simd aligned(B:bfoo())
+  for (int i = 0; i < 10; ++i) ;
+  // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'}}
+  #pragma omp simd aligned(B::ib:B:bfoo())
+  for (int i = 0; i < 10; ++i) ;
+  #pragma omp simd aligned(B:B::bfoo())
+  for (int i = 0; i < 10; ++i) ;
+  // expected-error at +1 {{unexpected ':' in nested name specifier; did you mean '::'?}}
+  #pragma omp simd aligned(z:B:bfoo())
+  for (int i = 0; i < 10; ++i) ;
+  #pragma omp simd aligned(B:B::bfoo())
+  for (int i = 0; i < 10; ++i) ;
+  // expected-error at +2 {{integral constant expression must have integral or unscoped enumeration type, not 'int **'}}
+  // expected-error at +1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'B'}}
+  #pragma omp simd aligned(X::x : ::z)
+  for (int i = 0; i < 10; ++i) ;
+  // expected-error at +1 {{integral constant expression must have integral or unscoped enumeration type, not 'B'}}
+  #pragma omp simd aligned(B,rp,::z: X::x)
+  for (int i = 0; i < 10; ++i) ;
+  #pragma omp simd aligned(::z)
+  for (int i = 0; i < 10; ++i) ;
+  // expected-error at +1 {{expected variable name}}
+  #pragma omp simd aligned(B::bfoo())
+  for (int i = 0; i < 10; ++i) ;
+  #pragma omp simd aligned(B::ib,B:C1+C2)
+  for (int i = 0; i < 10; ++i) ;
+}
+
+// expected-note at +1 {{'num' defined here}}
+template<int L, class T, class N> T test_template(T* arr, N num) {
+  N i;
+  T sum = (T)0;
+  T ind2 = - num * L;
+  // Negative number is passed as L.
+  // expected-error at +1 {{argument to 'aligned' clause must be a positive integer value}}
+  #pragma omp simd aligned(arr:L)
+  for (i = 0; i < num; ++i) {
+    T cur = arr[ind2];
+    ind2 += L;
+    sum += cur;
+  }
+  // expected-error at +1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+  #pragma omp simd aligned(num:4)
+  for (i = 0; i < num; ++i);
+}
+
+template<int LEN> int test_warn() {
+  int *ind2 = 0;
+  // expected-error at +1 {{argument to 'aligned' clause must be a positive integer value}}
+  #pragma omp simd aligned(ind2:LEN)
+  for (int i = 0; i < 100; i++) {
+    ind2 += LEN;
+  }
+  return 0;
+}
+
+struct S1; // expected-note 2 {{declared here}}
+extern S1 a; // expected-note {{'a' declared here}}
+class S2 {
+  mutable int a;
+public:
+  S2():a(0) { }
+};
+const S2 b; // expected-note 1 {{'b' defined here}}
+const S2 ba[5];
+class S3 {
+  int a;
+public:
+  S3():a(0) { }
+};
+const S3 ca[5];
+class S4 {
+  int a;
+  S4();
+public:
+  S4(int v):a(v) { }
+};
+class S5 {
+  int a;
+  S5():a(0) {}
+public:
+  S5(int v):a(v) { }
+};
+
+S3 h; // expected-note 2 {{'h' defined here}}
+#pragma omp threadprivate(h)
+
+template<class I, class C> int foomain(I argc, C **argv) {
+  I e(argc);
+  I g(argc);
+  int i; // expected-note {{declared here}} expected-note {{'i' defined here}}
+  // expected-note at +2 {{declared here}}
+  // expected-note at +1 {{reference to 'i' is not a constant expression}}
+  int &j = i;
+  #pragma omp simd aligned // expected-error {{expected '(' after 'aligned'}}
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned () // expected-error {{expected expression}}
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (argc : 5)
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (S1) // expected-error {{'S1' does not refer to a value}}
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (argv[1]) // expected-error {{expected variable name}}
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned(e, g)
+  for (I k = 0; k < argc; ++k) ++k;
+  // expected-error at +1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}}
+  #pragma omp simd aligned(h)
+  for (I k = 0; k < argc; ++k) ++k;
+  // expected-error at +1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+  #pragma omp simd aligned(i)
+  for (I k = 0; k < argc; ++k) ++k;
+  #pragma omp parallel
+  {
+    int *v = 0;
+    I i;
+    #pragma omp simd aligned(v:16)
+    for (I k = 0; k < argc; ++k) { i = k; v += 2; }
+  }
+  float *f;
+  #pragma omp simd aligned(f)
+  for (I k = 0; k < argc; ++k) ++k;
+  int v = 0;
+  // expected-note at +2 {{initializer of 'j' is not a constant expression}}
+  // expected-error at +1 {{expression is not an integral constant expression}}
+  #pragma omp simd aligned(f:j)
+  for (I k = 0; k < argc; ++k) { ++k; v += j; }
+  #pragma omp simd aligned(f)
+  for (I k = 0; k < argc; ++k) ++k;
+  return 0;
+}
+
+// expected-note at +1 2 {{'argc' defined here}}
+int main(int argc, char **argv) {
+  double darr[100];
+  // expected-note at +1 {{in instantiation of function template specialization 'test_template<-4, double, int>' requested here}}
+  test_template<-4>(darr, 4);
+  test_warn<4>(); // ok
+  // expected-note at +1 {{in instantiation of function template specialization 'test_warn<0>' requested here}}
+  test_warn<0>();
+
+  int i;
+  int &j = i;
+  #pragma omp simd aligned // expected-error {{expected '(' after 'aligned'}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned () // expected-error {{expected expression}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (argv // expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+  // expected-error at +1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+  #pragma omp simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+  // expected-error at +1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'int'}}
+  #pragma omp simd aligned (argc)
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (S1) // expected-error {{'S1' does not refer to a value}}
+  for (int k = 0; k < argc; ++k) ++k;
+  // expected-error at +2 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S1'}}
+  // expected-error at +1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S2'}}
+  #pragma omp simd aligned (a, b) 
+  for (int k = 0; k < argc; ++k) ++k;
+  #pragma omp simd aligned (argv[1]) // expected-error {{expected variable name}}
+  for (int k = 0; k < argc; ++k) ++k;
+  // expected-error at +1 {{argument of aligned clause should be array, pointer, reference to array or reference to pointer, not 'S3'}}
+  #pragma omp simd aligned(h)
+  for (int k = 0; k < argc; ++k) ++k;
+  int *pargc = &argc;
+  foomain<int*,char>(pargc,argv);
+  return 0;
+}
+

Modified: cfe/trunk/test/OpenMP/simd_ast_print.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/simd_ast_print.cpp?rev=209816&r1=209815&r2=209816&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/simd_ast_print.cpp (original)
+++ cfe/trunk/test/OpenMP/simd_ast_print.cpp Thu May 29 09:36:25 2014
@@ -14,8 +14,8 @@ template<class T, class N> T reduct(T* a
   N myind;
   T sum = (T)0;
 // CHECK: T sum = (T)0;
-#pragma omp simd private(myind, g_ind), linear(ind)
-// CHECK-NEXT: #pragma omp simd private(myind,g_ind) linear(ind)
+#pragma omp simd private(myind, g_ind), linear(ind), aligned(arr)
+// CHECK-NEXT: #pragma omp simd private(myind,g_ind) linear(ind) aligned(arr)
   for (i = 0; i < num; ++i) {
     myind = ind;
     T cur = arr[myind];
@@ -62,7 +62,7 @@ template<class T> struct S {
 template<int LEN> struct S2 {
   static void func(int n, float *a, float *b, float *c) {
     int k1 = 0, k2 = 0;
-#pragma omp simd safelen(LEN) linear(k1,k2:LEN)
+#pragma omp simd safelen(LEN) linear(k1,k2:LEN) aligned(a:LEN)
     for(int i = 0; i < n; i++) {
       c[i] = a[i] + b[i];
       c[k1] = a[k1] + b[k1];
@@ -77,7 +77,7 @@ template<int LEN> struct S2 {
 // CHECK: template <int LEN = 4> struct S2 {
 // CHECK-NEXT: static void func(int n, float *a, float *b, float *c)     {
 // CHECK-NEXT:   int k1 = 0, k2 = 0;
-// CHECK-NEXT: #pragma omp simd safelen(4) linear(k1,k2: 4)
+// CHECK-NEXT: #pragma omp simd safelen(4) linear(k1,k2: 4) aligned(a: 4)
 // CHECK-NEXT:   for (int i = 0; i < n; i++) {
 // CHECK-NEXT:     c[i] = a[i] + b[i];
 // CHECK-NEXT:     c[k1] = a[k1] + b[k1];
@@ -97,10 +97,10 @@ int main (int argc, char **argv) {
   for (int i=0; i < 2; ++i)*a=2;
 // CHECK-NEXT: for (int i = 0; i < 2; ++i)
 // CHECK-NEXT: *a = 2;
-#pragma omp simd private(argc, b) collapse(2)
+#pragma omp simd private(argc, b) collapse(2) aligned(a : 4)
   for (int i = 0; i < 10; ++i)
   for (int j = 0; j < 10; ++j) {foo(); k1 += 8; k2 += 8;}
-// CHECK-NEXT: #pragma omp simd private(argc,b) collapse(2)
+// CHECK-NEXT: #pragma omp simd private(argc,b) collapse(2) aligned(a: 4)
 // CHECK-NEXT: for (int i = 0; i < 10; ++i)
 // CHECK-NEXT: for (int j = 0; j < 10; ++j) {
 // CHECK-NEXT: foo();
@@ -112,8 +112,8 @@ int main (int argc, char **argv) {
 // CHECK-NEXT: foo();
   const int CLEN = 4;
 // CHECK-NEXT: const int CLEN = 4;
-  #pragma omp simd linear(a:CLEN) safelen(CLEN) collapse( 1 )
-// CHECK-NEXT: #pragma omp simd linear(a: CLEN) safelen(CLEN) collapse(1)
+  #pragma omp simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 )
+// CHECK-NEXT: #pragma omp simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1)
   for (int i = 0; i < 10; ++i)foo();
 // CHECK-NEXT: for (int i = 0; i < 10; ++i)
 // CHECK-NEXT: foo();

Modified: cfe/trunk/test/OpenMP/simd_misc_messages.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/simd_misc_messages.c?rev=209816&r1=209815&r2=209816&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/simd_misc_messages.c (original)
+++ cfe/trunk/test/OpenMP/simd_misc_messages.c Thu May 29 09:36:25 2014
@@ -292,6 +292,83 @@ void test_linear()
   for (i = 0; i < 16; ++i) ;
 }
 
+void test_aligned()
+{
+  int i;
+  // expected-error at +1 {{expected expression}} expected-error at +1 {{expected ')'}} expected-note at +1 {{to match this '('}}
+  #pragma omp simd aligned(
+  for (i = 0; i < 16; ++i) ;
+  // expected-error at +2 {{expected expression}}
+  // expected-error at +1 {{expected expression}} expected-error at +1 {{expected ')'}} expected-note at +1 {{to match this '('}}
+  #pragma omp simd aligned(,
+  for (i = 0; i < 16; ++i) ;
+  // expected-error at +2 {{expected expression}}
+  // expected-error at +1 {{expected expression}}
+  #pragma omp simd aligned(,)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error at +1 {{expected expression}}
+  #pragma omp simd aligned()
+  for (i = 0; i < 16; ++i) ;
+  // expected-error at +1 {{expected expression}}
+  #pragma omp simd aligned(int)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error at +1 {{expected variable name}}
+  #pragma omp simd aligned(0)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error at +1 {{use of undeclared identifier 'x'}}
+  #pragma omp simd aligned(x)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error at +2 {{use of undeclared identifier 'x'}}
+  // expected-error at +1 {{use of undeclared identifier 'y'}}
+  #pragma omp simd aligned(x, y)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error at +3 {{use of undeclared identifier 'x'}}
+  // expected-error at +2 {{use of undeclared identifier 'y'}}
+  // expected-error at +1 {{use of undeclared identifier 'z'}}
+  #pragma omp simd aligned(x, y, z)
+  for (i = 0; i < 16; ++i) ;
+
+  int *x, y, z[25]; // expected-note 4 {{'y' defined here}}
+  #pragma omp simd aligned(x)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd aligned(z)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error at +1 {{expected expression}}
+  #pragma omp simd aligned(x:)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error at +1 {{expected expression}} expected-error at +1 {{expected ')'}} expected-note at +1 {{to match this '('}}
+  #pragma omp simd aligned(x:,)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd aligned(x:1)
+  for (i = 0; i < 16; ++i) ;
+  #pragma omp simd aligned(x:2*2)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error at +1 {{expected ')'}} expected-note at +1 {{to match this '('}}
+  #pragma omp simd aligned(x:1,y)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error at +1 {{expected ')'}} expected-note at +1 {{to match this '('}}
+  #pragma omp simd aligned(x:1,y,z:1)
+  for (i = 0; i < 16; ++i) ;
+
+  // expected-error at +1 {{argument of aligned clause should be array or pointer, not 'int'}}
+  #pragma omp simd aligned(x, y)
+  for (i = 0; i < 16; ++i) ;
+  // expected-error at +1 {{argument of aligned clause should be array or pointer, not 'int'}}
+  #pragma omp simd aligned(x, y, z)
+  for (i = 0; i < 16; ++i) ;
+
+  // expected-note at +2 {{defined as aligned}}
+  // expected-error at +1 {{a variable cannot appear in more than one aligned clause}}
+  #pragma omp simd aligned(x) aligned(z,x)
+  for (i = 0; i < 16; ++i) ;
+
+  // expected-note at +3 {{defined as aligned}}
+  // expected-error at +2 {{a variable cannot appear in more than one aligned clause}}
+  // expected-error at +1 2 {{argument of aligned clause should be array or pointer, not 'int'}}
+  #pragma omp simd aligned(x,y,z) aligned(y,z)
+  for (i = 0; i < 16; ++i) ;
+}
+
 void test_private()
 {
   int i;

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=209816&r1=209815&r2=209816&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Thu May 29 09:36:25 2014
@@ -1963,6 +1963,10 @@ void OMPClauseEnqueue::VisitOMPLinearCla
   VisitOMPClauseList(C);
   Visitor->AddStmt(C->getStep());
 }
+void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
+  VisitOMPClauseList(C);
+  Visitor->AddStmt(C->getAlignment());
+}
 void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
   VisitOMPClauseList(C);
 }





More information about the cfe-commits mailing list