[cfe-commits] r130351 - in /cfe/trunk: include/clang/AST/ include/clang/Basic/ include/clang/Parse/ include/clang/Sema/ include/clang/Serialization/ lib/AST/ lib/CodeGen/ lib/Parse/ lib/Sema/ lib/Serialization/ lib/StaticAnalyzer/Core/ test/SemaCXX/ tools/libclang/

John Wiegley johnw at boostpro.com
Wed Apr 27 17:16:57 PDT 2011


Author: johnw
Date: Wed Apr 27 19:16:57 2011
New Revision: 130351

URL: http://llvm.org/viewvc/llvm-project?rev=130351&view=rev
Log:
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).

Modified:
    cfe/trunk/include/clang/AST/ExprCXX.h
    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
    cfe/trunk/include/clang/Basic/StmtNodes.td
    cfe/trunk/include/clang/Basic/TokenKinds.def
    cfe/trunk/include/clang/Basic/TypeTraits.h
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h
    cfe/trunk/lib/AST/ExprClassification.cpp
    cfe/trunk/lib/AST/ExprConstant.cpp
    cfe/trunk/lib/AST/ItaniumMangle.cpp
    cfe/trunk/lib/AST/StmtPrinter.cpp
    cfe/trunk/lib/AST/StmtProfile.cpp
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/Parse/ParseExpr.cpp
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
    cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
    cfe/trunk/test/SemaCXX/type-traits.cpp
    cfe/trunk/tools/libclang/CIndex.cpp
    cfe/trunk/tools/libclang/CXCursor.cpp

Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=130351&r1=130350&r2=130351&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Wed Apr 27 19:16:57 2011
@@ -1594,6 +1594,68 @@
   friend class ASTStmtReader;
 };
 
+/// ArrayTypeTraitExpr - An Embarcadero array type trait, as used in the
+/// implementation of __array_rank and __array_extent.
+/// Example:
+/// __array_rank(int[10][20]) == 2
+/// __array_extent(int, 1)    == 20
+class ArrayTypeTraitExpr : public Expr {
+  /// ATT - The trait. An ArrayTypeTrait enum in MSVC compat unsigned.
+  unsigned ATT : 2;
+
+  /// The value of the type trait. Unspecified if dependent.
+  uint64_t Value;
+
+  /// The array dimension being queried, or -1 if not used
+  Expr *Dimension;
+
+  /// Loc - The location of the type trait keyword.
+  SourceLocation Loc;
+
+  /// RParen - The location of the closing paren.
+  SourceLocation RParen;
+
+  /// The type being queried.
+  TypeSourceInfo *QueriedType;
+
+public:
+  ArrayTypeTraitExpr(SourceLocation loc, ArrayTypeTrait att,
+                     TypeSourceInfo *queried, uint64_t value,
+                     Expr *dimension, SourceLocation rparen, QualType ty)
+    : Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary,
+           false, queried->getType()->isDependentType(),
+           queried->getType()->containsUnexpandedParameterPack()),
+      ATT(att), Value(value), Dimension(dimension),
+      Loc(loc), RParen(rparen), QueriedType(queried) { }
+
+
+  explicit ArrayTypeTraitExpr(EmptyShell Empty)
+    : Expr(ArrayTypeTraitExprClass, Empty), ATT(0), Value(false),
+      QueriedType() { }
+
+  virtual SourceRange getSourceRange() const { return SourceRange(Loc, RParen); }
+
+  ArrayTypeTrait getTrait() const { return static_cast<ArrayTypeTrait>(ATT); }
+
+  QualType getQueriedType() const { return QueriedType->getType(); }
+
+  TypeSourceInfo *getQueriedTypeSourceInfo() const { return QueriedType; }
+
+  uint64_t getValue() const { assert(!isTypeDependent()); return Value; }
+
+  Expr *getDimensionExpression() const { return Dimension; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ArrayTypeTraitExprClass;
+  }
+  static bool classof(const ArrayTypeTraitExpr *) { return true; }
+
+  // Iterators
+  child_range children() { return child_range(); }
+
+  friend class ASTStmtReader;
+};
+
 /// ExpressionTraitExpr - An expression trait intrinsic
 /// Example:
 /// __is_lvalue_expr(std::cout) == true

Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=130351&r1=130350&r2=130351&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Wed Apr 27 19:16:57 2011
@@ -1849,6 +1849,10 @@
     TRY_TO(TraverseTypeLoc(S->getRhsTypeSourceInfo()->getTypeLoc()));
   })
 
+DEF_TRAVERSE_STMT(ArrayTypeTraitExpr, {
+    TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
+  })
+
 DEF_TRAVERSE_STMT(ExpressionTraitExpr, {
     TRY_TO(TraverseStmt(S->getQueriedExpression()));
   })

Modified: cfe/trunk/include/clang/Basic/StmtNodes.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/StmtNodes.td?rev=130351&r1=130350&r2=130351&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/StmtNodes.td (original)
+++ cfe/trunk/include/clang/Basic/StmtNodes.td Wed Apr 27 19:16:57 2011
@@ -104,6 +104,7 @@
 def CXXPseudoDestructorExpr : DStmt<Expr>;
 def UnaryTypeTraitExpr : DStmt<Expr>;
 def BinaryTypeTraitExpr : DStmt<Expr>;
+def ArrayTypeTraitExpr : DStmt<Expr>;
 def ExpressionTraitExpr : DStmt<Expr>;
 def DependentScopeDeclRefExpr : DStmt<Expr>;
 def CXXConstructExpr : DStmt<Expr>;

Modified: cfe/trunk/include/clang/Basic/TokenKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=130351&r1=130350&r2=130351&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TokenKinds.def (original)
+++ cfe/trunk/include/clang/Basic/TokenKinds.def Wed Apr 27 19:16:57 2011
@@ -378,6 +378,8 @@
 // Embarcadero Binary Type Traits
 KEYWORD(__is_same                   , KEYCXX)
 KEYWORD(__is_convertible            , KEYCXX)
+KEYWORD(__array_rank                , KEYCXX)
+KEYWORD(__array_extent              , KEYCXX)
 
 // Apple Extension.
 KEYWORD(__private_extern__          , KEYALL)

Modified: cfe/trunk/include/clang/Basic/TypeTraits.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TypeTraits.h?rev=130351&r1=130350&r2=130351&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TypeTraits.h (original)
+++ cfe/trunk/include/clang/Basic/TypeTraits.h Wed Apr 27 19:16:57 2011
@@ -71,6 +71,12 @@
     BTT_TypeCompatible
   };
 
+  /// ArrayTypeTrait - Names for the array type traits.
+  enum ArrayTypeTrait {
+    ATT_ArrayRank,
+    ATT_ArrayExtent
+  };
+
   /// UnaryExprOrTypeTrait - Names for the "expression or type" traits.
   enum UnaryExprOrTypeTrait {
     UETT_SizeOf,

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=130351&r1=130350&r2=130351&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Wed Apr 27 19:16:57 2011
@@ -1816,7 +1816,8 @@
   ExprResult ParseBinaryTypeTrait();
 
   //===--------------------------------------------------------------------===//
-  // Embarcadero: Expression Traits
+  // Embarcadero: Arary and Expression Traits
+  ExprResult ParseArrayTypeTrait();
   ExprResult ParseExpressionTrait();
 
   //===--------------------------------------------------------------------===//

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=130351&r1=130350&r2=130351&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Apr 27 19:16:57 2011
@@ -2736,6 +2736,20 @@
                                   TypeSourceInfo *RhsT,
                                   SourceLocation RParen);
 
+  /// ActOnArrayTypeTrait - Parsed one of the bianry type trait support
+  /// pseudo-functions.
+  ExprResult ActOnArrayTypeTrait(ArrayTypeTrait ATT,
+                                 SourceLocation KWLoc,
+                                 ParsedType LhsTy,
+                                 Expr *DimExpr,
+                                 SourceLocation RParen);
+
+  ExprResult BuildArrayTypeTrait(ArrayTypeTrait ATT,
+                                 SourceLocation KWLoc,
+                                 TypeSourceInfo *TSInfo,
+                                 Expr *DimExpr,
+                                 SourceLocation RParen);
+
   /// ActOnExpressionTrait - Parsed one of the unary type trait support
   /// pseudo-functions.
   ExprResult ActOnExpressionTrait(ExpressionTrait OET,

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=130351&r1=130350&r2=130351&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Wed Apr 27 19:16:57 2011
@@ -978,6 +978,7 @@
       EXPR_OPAQUE_VALUE,          // OpaqueValueExpr
       EXPR_BINARY_CONDITIONAL_OPERATOR,  // BinaryConditionalOperator
       EXPR_BINARY_TYPE_TRAIT,     // BinaryTypeTraitExpr
+      EXPR_ARRAY_TYPE_TRAIT,      // ArrayTypeTraitIntExpr
       
       EXPR_PACK_EXPANSION,        // PackExpansionExpr
       EXPR_SIZEOF_PACK,           // SizeOfPackExpr

Modified: cfe/trunk/lib/AST/ExprClassification.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprClassification.cpp?rev=130351&r1=130350&r2=130351&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprClassification.cpp (original)
+++ cfe/trunk/lib/AST/ExprClassification.cpp Wed Apr 27 19:16:57 2011
@@ -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:

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=130351&r1=130350&r2=130351&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Wed Apr 27 19:16:57 2011
@@ -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();

Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=130351&r1=130350&r2=130351&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Wed Apr 27 19:16:57 2011
@@ -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:

Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=130351&r1=130350&r2=130351&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Wed Apr 27 19:16:57 2011
@@ -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());

Modified: cfe/trunk/lib/AST/StmtProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=130351&r1=130350&r2=130351&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtProfile.cpp (original)
+++ cfe/trunk/lib/AST/StmtProfile.cpp Wed Apr 27 19:16:57 2011
@@ -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());

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=130351&r1=130350&r2=130351&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Wed Apr 27 19:16:57 2011
@@ -367,6 +367,10 @@
     return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
   }
 
+  Value *VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
+    return llvm::ConstantInt::get(Builder.getInt32Ty(), E->getValue());
+  }
+
   Value *VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
     return llvm::ConstantInt::get(Builder.getInt1Ty(), E->getValue());
   }

Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=130351&r1=130350&r2=130351&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Wed Apr 27 19:16:57 2011
@@ -490,6 +490,7 @@
 /// [C++]   'this'          [C++ 9.3.2]
 /// [G++]   unary-type-trait '(' type-id ')'
 /// [G++]   binary-type-trait '(' type-id ',' type-id ')'           [TODO]
+/// [EMBT]  array-type-trait '(' type-id ',' integer ')'
 /// [clang] '^' block-literal
 ///
 ///       constant: [C99 6.4.4]
@@ -571,6 +572,10 @@
 ///                   '__is_convertible'
 ///                   '__is_same'
 ///
+/// [Embarcadero] array-type-trait:
+///                   '__array_rank'
+///                   '__array_extent'
+///
 /// [Embarcadero] expression-trait:
 ///                   '__is_lvalue_expr'
 ///                   '__is_rvalue_expr'
@@ -1072,6 +1077,10 @@
   case tok::kw___is_convertible_to:
     return ParseBinaryTypeTrait();
 
+  case tok::kw___array_rank:
+  case tok::kw___array_extent:
+    return ParseArrayTypeTrait();
+
   case tok::kw___is_lvalue_expr:
   case tok::kw___is_rvalue_expr:
     return ParseExpressionTrait();

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=130351&r1=130350&r2=130351&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Wed Apr 27 19:16:57 2011
@@ -1970,6 +1970,14 @@
   }
 }
 
+static ArrayTypeTrait ArrayTypeTraitFromTokKind(tok::TokenKind kind) {
+  switch(kind) {
+  default: llvm_unreachable("Not a known binary type trait");
+  case tok::kw___array_rank:                 return ATT_ArrayRank;
+  case tok::kw___array_extent:               return ATT_ArrayExtent;
+  }
+}
+
 static ExpressionTrait ExpressionTraitFromTokKind(tok::TokenKind kind) {
   switch(kind) {
   default: assert(false && "Not a known unary expression trait.");
@@ -2043,6 +2051,50 @@
   return Actions.ActOnBinaryTypeTrait(BTT, Loc, LhsTy.get(), RhsTy.get(), RParen);
 }
 
+/// ParseArrayTypeTrait - Parse the built-in array type-trait
+/// pseudo-functions.
+///
+///       primary-expression:
+/// [Embarcadero]     '__array_rank' '(' type-id ')'
+/// [Embarcadero]     '__array_extent' '(' type-id ',' expression ')'
+///
+ExprResult Parser::ParseArrayTypeTrait() {
+  ArrayTypeTrait ATT = ArrayTypeTraitFromTokKind(Tok.getKind());
+  SourceLocation Loc = ConsumeToken();
+
+  SourceLocation LParen = Tok.getLocation();
+  if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen))
+    return ExprError();
+
+  TypeResult Ty = ParseTypeName();
+  if (Ty.isInvalid()) {
+    SkipUntil(tok::comma);
+    SkipUntil(tok::r_paren);
+    return ExprError();
+  }
+
+  switch (ATT) {
+  case ATT_ArrayRank: {
+    SourceLocation RParen = MatchRHSPunctuation(tok::r_paren, LParen);
+    return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), NULL, RParen);
+  }
+  case ATT_ArrayExtent: {
+    if (ExpectAndConsume(tok::comma, diag::err_expected_comma)) {
+      SkipUntil(tok::r_paren);
+      return ExprError();
+    }
+
+    ExprResult DimExpr = ParseExpression();
+    SourceLocation RParen = MatchRHSPunctuation(tok::r_paren, LParen);
+
+    return Actions.ActOnArrayTypeTrait(ATT, Loc, Ty.get(), DimExpr.get(), RParen);
+  }
+  default:
+    break;
+  }
+  return ExprError();
+}
+
 /// ParseExpressionTrait - Parse built-in expression-trait
 /// pseudo-functions like __is_lvalue_expr( xxx ).
 ///

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=130351&r1=130350&r2=130351&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Apr 27 19:16:57 2011
@@ -2812,6 +2812,94 @@
                                                  ResultType));
 }
 
+ExprResult Sema::ActOnArrayTypeTrait(ArrayTypeTrait ATT,
+                                     SourceLocation KWLoc,
+                                     ParsedType Ty,
+                                     Expr* DimExpr,
+                                     SourceLocation RParen) {
+  TypeSourceInfo *TSInfo;
+  QualType T = GetTypeFromParser(Ty, &TSInfo);
+  if (!TSInfo)
+    TSInfo = Context.getTrivialTypeSourceInfo(T);
+
+  return BuildArrayTypeTrait(ATT, KWLoc, TSInfo, DimExpr, RParen);
+}
+
+static uint64_t EvaluateArrayTypeTrait(Sema &Self, ArrayTypeTrait ATT,
+                                           QualType T, Expr *DimExpr,
+                                           SourceLocation KeyLoc) {
+  assert((!T->isDependentType()) &&
+         "Cannot evaluate traits for dependent types.");
+
+  switch(ATT) {
+  case ATT_ArrayRank:
+    if (T->isArrayType()) {
+      unsigned Dim = 0;
+      while (const ArrayType *AT = Self.Context.getAsArrayType(T)) {
+        ++Dim;
+        T = AT->getElementType();
+      }
+      return Dim;
+    } else {
+      assert(! "Array type trait applied to non-array type");
+    }
+  case ATT_ArrayExtent: {
+    llvm::APSInt Value;
+    uint64_t Dim;
+    if (DimExpr->isIntegerConstantExpr(Value, Self.Context, 0, false))
+      Dim = Value.getLimitedValue();
+    else
+      assert(! "Dimension expression did not evaluate to a constant integer");
+
+    if (T->isArrayType()) {
+      unsigned D = 0;
+      bool Matched = false;
+      while (const ArrayType *AT = Self.Context.getAsArrayType(T)) {
+        if (Dim == D) {
+          Matched = true;
+          break;
+        }
+        ++D;
+        T = AT->getElementType();
+      }
+
+      assert(Matched && T->isArrayType() &&
+             "__array_extent does not refer to an array dimension");
+
+      llvm::APInt size = Self.Context.getAsConstantArrayType(T)->getSize();
+      return size.getLimitedValue();
+    } else {
+      assert(! "Array type trait applied to non-array type");
+    }
+  }
+  }
+  llvm_unreachable("Unknown type trait or not implemented");
+}
+
+ExprResult Sema::BuildArrayTypeTrait(ArrayTypeTrait ATT,
+                                     SourceLocation KWLoc,
+                                     TypeSourceInfo *TSInfo,
+                                     Expr* DimExpr,
+                                     SourceLocation RParen) {
+  QualType T = TSInfo->getType();
+
+  uint64_t Value;
+  if (!T->isDependentType())
+    Value = EvaluateArrayTypeTrait(*this, ATT, T, DimExpr, KWLoc);
+  else
+    return ExprError();
+
+  // Select trait result type.
+  QualType ResultType;
+  switch (ATT) {
+  case ATT_ArrayRank:    ResultType = Context.IntTy; break;
+  case ATT_ArrayExtent:  ResultType = Context.IntTy; break;
+  }
+
+  return Owned(new (Context) ArrayTypeTraitExpr(KWLoc, ATT, TSInfo, Value,
+                                                DimExpr, RParen, ResultType));
+}
+
 ExprResult Sema::ActOnExpressionTrait(ExpressionTrait ET,
                                      SourceLocation KWLoc,
                                      Expr* Queried,

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=130351&r1=130350&r2=130351&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Wed Apr 27 19:16:57 2011
@@ -1915,6 +1915,18 @@
     return getSema().BuildBinaryTypeTrait(Trait, StartLoc, LhsT, RhsT, RParenLoc);
   }
 
+  /// \brief Build a new array type trait expression.
+  ///
+  /// By default, performs semantic analysis to build the new expression.
+  /// Subclasses may override this routine to provide different behavior.
+  ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,
+                                   SourceLocation StartLoc,
+                                   TypeSourceInfo *TSInfo,
+                                   Expr *DimExpr,
+                                   SourceLocation RParenLoc) {
+    return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
+  }
+
   /// \brief Build a new expression trait expression.
   ///
   /// By default, performs semantic analysis to build the new expression.
@@ -6921,6 +6933,35 @@
 
 template<typename Derived>
 ExprResult
+TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
+  TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
+  if (!T)
+    return ExprError();
+
+  if (!getDerived().AlwaysRebuild() &&
+      T == E->getQueriedTypeSourceInfo())
+    return SemaRef.Owned(E);
+
+  ExprResult SubExpr;
+  {
+    EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
+    SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
+    if (SubExpr.isInvalid())
+      return ExprError();
+
+    if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getDimensionExpression())
+      return SemaRef.Owned(E);
+  }
+
+  return getDerived().RebuildArrayTypeTrait(E->getTrait(),
+                                            E->getLocStart(),
+                                            T,
+                                            SubExpr.get(),
+                                            E->getLocEnd());
+}
+
+template<typename Derived>
+ExprResult
 TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
   ExprResult SubExpr;
   {

Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=130351&r1=130350&r2=130351&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Wed Apr 27 19:16:57 2011
@@ -179,6 +179,7 @@
 
     void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
     void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
+    void VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E);
     void VisitExpressionTraitExpr(ExpressionTraitExpr *E);
     void VisitCXXNoexceptExpr(CXXNoexceptExpr *E);
     void VisitPackExpansionExpr(PackExpansionExpr *E);
@@ -1344,6 +1345,16 @@
   E->RhsType = GetTypeSourceInfo(Record, Idx);
 }
 
+void ASTStmtReader::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
+  VisitExpr(E);
+  E->ATT = (ArrayTypeTrait)Record[Idx++];
+  E->Value = (unsigned int)Record[Idx++];
+  SourceRange Range = ReadSourceRange(Record, Idx);
+  E->Loc = Range.getBegin();
+  E->RParen = Range.getEnd();
+  E->QueriedType = GetTypeSourceInfo(Record, Idx);
+}
+
 void ASTStmtReader::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
   VisitExpr(E);
   E->ET = (ExpressionTrait)Record[Idx++];
@@ -1946,6 +1957,10 @@
       S = new (Context) BinaryTypeTraitExpr(Empty);
       break;
 
+    case EXPR_ARRAY_TYPE_TRAIT:
+      S = new (Context) ArrayTypeTraitExpr(Empty);
+      break;
+
     case EXPR_CXX_EXPRESSION_TRAIT:
       S = new (Context) ExpressionTraitExpr(Empty);
       break;

Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=130351&r1=130350&r2=130351&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Wed Apr 27 19:16:57 2011
@@ -153,6 +153,7 @@
 
     void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
     void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
+    void VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E);
     void VisitExpressionTraitExpr(ExpressionTraitExpr *E);
     void VisitCXXNoexceptExpr(CXXNoexceptExpr *E);
     void VisitPackExpansionExpr(PackExpansionExpr *E);
@@ -1340,6 +1341,15 @@
   Code = serialization::EXPR_BINARY_TYPE_TRAIT;
 }
 
+void ASTStmtWriter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->getTrait());
+  Record.push_back(E->getValue());
+  Writer.AddSourceRange(E->getSourceRange(), Record);
+  Writer.AddTypeSourceInfo(E->getQueriedTypeSourceInfo(), Record);
+  Code = serialization::EXPR_ARRAY_TYPE_TRAIT;
+}
+
 void ASTStmtWriter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
   VisitExpr(E);
   Record.push_back(E->getTrait());

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=130351&r1=130350&r2=130351&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Wed Apr 27 19:16:57 2011
@@ -435,6 +435,7 @@
     case Stmt::DependentScopeDeclRefExprClass:
     case Stmt::UnaryTypeTraitExprClass:
     case Stmt::BinaryTypeTraitExprClass:
+    case Stmt::ArrayTypeTraitExprClass:
     case Stmt::ExpressionTraitExprClass:
     case Stmt::UnresolvedLookupExprClass:
     case Stmt::UnresolvedMemberExprClass:

Modified: cfe/trunk/test/SemaCXX/type-traits.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/type-traits.cpp?rev=130351&r1=130350&r2=130351&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/type-traits.cpp (original)
+++ cfe/trunk/test/SemaCXX/type-traits.cpp Wed Apr 27 19:16:57 2011
@@ -1464,3 +1464,14 @@
   { int arr[F(__is_trivial(void))]; }
   { int arr[F(__is_trivial(cvoid))]; }
 }
+
+void array_rank() {
+  int t01[T(__array_rank(IntAr) == 1)];
+  int t02[T(__array_rank(ConstIntArAr) == 2)];
+}
+
+void array_extent() {
+  int t01[T(__array_extent(IntAr, 0) == 10)];
+  int t02[T(__array_extent(ConstIntArAr, 0) == 4)];
+  int t03[T(__array_extent(ConstIntArAr, 1) == 10)];
+}

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=130351&r1=130350&r2=130351&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Wed Apr 27 19:16:57 2011
@@ -1790,6 +1790,7 @@
   void VisitWhileStmt(WhileStmt *W);
   void VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E);
   void VisitBinaryTypeTraitExpr(BinaryTypeTraitExpr *E);
+  void VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E);
   void VisitExpressionTraitExpr(ExpressionTraitExpr *E);
   void VisitUnresolvedMemberExpr(UnresolvedMemberExpr *U);
   void VisitVAArgExpr(VAArgExpr *E);
@@ -2070,6 +2071,7 @@
   AddStmt(W->getCond());
   AddDecl(W->getConditionVariable());
 }
+
 void EnqueueVisitor::VisitUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
   AddTypeLoc(E->getQueriedTypeSourceInfo());
 }
@@ -2079,6 +2081,10 @@
   AddTypeLoc(E->getLhsTypeSourceInfo());
 }
 
+void EnqueueVisitor::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
+  AddTypeLoc(E->getQueriedTypeSourceInfo());
+}
+
 void EnqueueVisitor::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
   EnqueueChildren(E);
 }

Modified: cfe/trunk/tools/libclang/CXCursor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXCursor.cpp?rev=130351&r1=130350&r2=130351&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CXCursor.cpp (original)
+++ cfe/trunk/tools/libclang/CXCursor.cpp Wed Apr 27 19:16:57 2011
@@ -151,6 +151,7 @@
   case Stmt::UnresolvedLookupExprClass:   
   case Stmt::UnaryTypeTraitExprClass:     
   case Stmt::BinaryTypeTraitExprClass:     
+  case Stmt::ArrayTypeTraitExprClass:
   case Stmt::ExpressionTraitExprClass:     
   case Stmt::DependentScopeDeclRefExprClass:  
   case Stmt::CXXBindTemporaryExprClass:   





More information about the cfe-commits mailing list