Introduce the notion of literal types, as specified in C++0x.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90361 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 349487f..16b6dd7 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -791,6 +791,10 @@
/// isPODType - Return true if this is a plain-old-data type (C++ 3.9p10).
bool isPODType() const;
+ /// isLiteralType - Return true if this is a literal type
+ /// (C++0x [basic.types]p10)
+ bool isLiteralType() const;
+
/// isVariablyModifiedType (C99 6.7.5.2p2) - Return true for variable array
/// types that have a non-constant expression. This does not include "[]".
bool isVariablyModifiedType() const;
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index 9942233..bb022f1 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -324,6 +324,8 @@
KEYWORD(__is_pod , KEYCXX)
KEYWORD(__is_polymorphic , KEYCXX)
KEYWORD(__is_union , KEYCXX)
+// Tentative name - there's no implementation of std::is_literal_type yet.
+KEYWORD(__is_literal , KEYCXX)
// FIXME: Add MS's traits, too.
// Apple Extension.
diff --git a/include/clang/Basic/TypeTraits.h b/include/clang/Basic/TypeTraits.h
index 2a2eacc..36b8300 100644
--- a/include/clang/Basic/TypeTraits.h
+++ b/include/clang/Basic/TypeTraits.h
@@ -32,7 +32,8 @@
UTT_IsEnum,
UTT_IsPOD,
UTT_IsPolymorphic,
- UTT_IsUnion
+ UTT_IsUnion,
+ UTT_IsLiteral
};
}
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 7a6fbdc..a9f96ad 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -199,6 +199,7 @@
switch(UTT) {
default: assert(false && "Unknown type trait or not implemented");
case UTT_IsPOD: return QueriedType->isPODType();
+ case UTT_IsLiteral: return QueriedType->isLiteralType();
case UTT_IsClass: // Fallthrough
case UTT_IsUnion:
if (const RecordType *Record = QueriedType->getAs<RecordType>()) {
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 5a2434d..70387c7 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -639,6 +639,40 @@
}
}
+bool Type::isLiteralType() const {
+ if (isIncompleteType())
+ return false;
+
+ // C++0x [basic.types]p10:
+ // A type is a literal type if it is:
+ switch (CanonicalType->getTypeClass()) {
+ // We're whitelisting
+ default: return false;
+
+ // -- a scalar type
+ case Builtin:
+ case Complex:
+ case Pointer:
+ case MemberPointer:
+ case Vector:
+ case ExtVector:
+ case ObjCObjectPointer:
+ case Enum:
+ return true;
+
+ // -- a class type with ...
+ case Record:
+ // FIXME: Do the tests
+ return false;
+
+ // -- an array of literal type
+ // Extension: variable arrays cannot be literal types, since they're
+ // runtime-sized.
+ case ConstantArray:
+ return cast<ArrayType>(CanonicalType)->getElementType()->isLiteralType();
+ }
+}
+
bool Type::isPromotableIntegerType() const {
if (const BuiltinType *BT = getAs<BuiltinType>())
switch (BT->getKind()) {
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index f780cf1..7b8bc3e 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -826,6 +826,7 @@
case tok::kw___is_empty:
case tok::kw___is_polymorphic:
case tok::kw___is_abstract:
+ case tok::kw___is_literal:
case tok::kw___has_trivial_constructor:
case tok::kw___has_trivial_copy:
case tok::kw___has_trivial_assign:
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 52003e6..4eb6cd5 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -1459,6 +1459,7 @@
case tok::kw___is_pod: return UTT_IsPOD;
case tok::kw___is_polymorphic: return UTT_IsPolymorphic;
case tok::kw___is_union: return UTT_IsUnion;
+ case tok::kw___is_literal: return UTT_IsLiteral;
}
}
diff --git a/test/SemaCXX/literal-type.cpp b/test/SemaCXX/literal-type.cpp
new file mode 100644
index 0000000..0dca9c9
--- /dev/null
+++ b/test/SemaCXX/literal-type.cpp
@@ -0,0 +1,10 @@
+// RUN: clang-cc -fsyntax-only -verify -std=c++0x %s
+
+static_assert(__is_literal(int), "fail");
+static_assert(__is_literal(void*), "fail");
+enum E { E1 };
+static_assert(__is_literal(E), "fail");
+static_assert(__is_literal(decltype(E1)), "fail");
+typedef int IAR[10];
+static_assert(__is_literal(IAR), "fail");
+// FIXME: Records