[OPENMP 4.0] Parsing/sema analysis for 'simdlen' clause in 'declare simd'
construct.

OpenMP 4.0 defines '#pragma omp declare simd' construct that may have
associated 'simdlen' clause with constant positive expression as an
argument:
simdlen(<const_expr>)
Patch adds parsin and semantic analysis for simdlen clause.

llvm-svn: 265668
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 2d87b04..c60a17a 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -235,6 +235,22 @@
                 Attr.getSpellingListIndex(), /*InInstantiation=*/true);
 }
 
+/// Instantiation of 'declare simd' attribute and its arguments.
+static void instantiateOMPDeclareSimdDeclAttr(
+    Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
+    const OMPDeclareSimdDeclAttr &Attr, Decl *New) {
+  ExprResult Simdlen;
+  if (auto *E = Attr.getSimdlen()) {
+    Simdlen = S.SubstExpr(E, TemplateArgs);
+    if (Simdlen.isInvalid())
+      return;
+  }
+
+  (void)S.ActOnOpenMPDeclareSimdDirective(S.ConvertDeclToDeclGroup(New),
+                                          Attr.getBranchState(), Simdlen.get(),
+                                          Attr.getRange());
+}
+
 void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
                             const Decl *Tmpl, Decl *New,
                             LateInstantiatedAttrVec *LateAttrs,
@@ -278,6 +294,11 @@
       continue;
     }
 
+    if (const auto *OMPAttr = dyn_cast<OMPDeclareSimdDeclAttr>(TmplAttr)) {
+      instantiateOMPDeclareSimdDeclAttr(*this, TemplateArgs, *OMPAttr, New);
+      continue;
+    }
+
     // Existing DLL attribute on the instantiation takes precedence.
     if (TmplAttr->getKind() == attr::DLLExport ||
         TmplAttr->getKind() == attr::DLLImport) {