Implementation of Embarcadero array type traits

Patch authored by John Wiegley.

These are array type traits used for parsing code that employs certain
features of the Embarcadero C++ compiler: __array_rank(T) and
__array_extent(T, Dim).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130351 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp
index ebbdf94..888a93c 100644
--- a/lib/AST/ExprClassification.cpp
+++ b/lib/AST/ExprClassification.cpp
@@ -152,6 +152,7 @@
   case Expr::CXXScalarValueInitExprClass:
   case Expr::UnaryTypeTraitExprClass:
   case Expr::BinaryTypeTraitExprClass:
+  case Expr::ArrayTypeTraitExprClass:
   case Expr::ExpressionTraitExprClass:
   case Expr::ObjCSelectorExprClass:
   case Expr::ObjCProtocolExprClass:
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 519bbaa..c2caf8d 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -1061,6 +1061,10 @@
     return Success(E->getValue(), E);
   }
 
+  bool VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
+    return Success(E->getValue(), E);
+  }
+
   bool VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
     return Success(E->getValue(), E);
   }
@@ -2879,6 +2883,7 @@
   case Expr::CXXScalarValueInitExprClass:
   case Expr::UnaryTypeTraitExprClass:
   case Expr::BinaryTypeTraitExprClass:
+  case Expr::ArrayTypeTraitExprClass:
   case Expr::ExpressionTraitExprClass:
   case Expr::CXXNoexceptExprClass:
     return NoDiag();
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 14ee74b..82de578 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -1911,6 +1911,7 @@
   case Expr::StmtExprClass:
   case Expr::UnaryTypeTraitExprClass:
   case Expr::BinaryTypeTraitExprClass:
+  case Expr::ArrayTypeTraitExprClass:
   case Expr::ExpressionTraitExprClass:
   case Expr::VAArgExprClass:
   case Expr::CXXUuidofExprClass:
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index b96591b..62f06db 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -1308,6 +1308,14 @@
   return "";
 }
 
+static const char *getTypeTraitName(ArrayTypeTrait ATT) {
+  switch (ATT) {
+  case ATT_ArrayRank:        return "__array_rank";
+  case ATT_ArrayExtent:      return "__array_extent";
+  }
+  return "";
+}
+
 static const char *getExpressionTraitName(ExpressionTrait ET) {
   switch (ET) {
   default: llvm_unreachable("Unknown expression trait");
@@ -1328,6 +1336,11 @@
      << E->getRhsType().getAsString(Policy) << ")";
 }
 
+void StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
+  OS << getTypeTraitName(E->getTrait()) << "("
+     << E->getQueriedType().getAsString(Policy) << ")";
+}
+
 void StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
     OS << getExpressionTraitName(E->getTrait()) << "(";
     PrintExpr(E->getQueriedExpression());
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index fe9a10b..7a3fc54 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -802,6 +802,12 @@
   VisitType(S->getRhsType());
 }
 
+void StmtProfiler::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *S) {
+  VisitExpr(S);
+  ID.AddInteger(S->getTrait());
+  VisitType(S->getQueriedType());
+}
+
 void StmtProfiler::VisitExpressionTraitExpr(ExpressionTraitExpr *S) {
   VisitExpr(S);
   ID.AddInteger(S->getTrait());