summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bindings/python/clang/cindex.py65
-rw-r--r--include/clang-c/Index.h17
-rw-r--r--test/Index/print-type-cxx11.cpp8
-rw-r--r--tools/c-index-test/c-index-test.c5
-rw-r--r--tools/libclang/CXType.cpp18
-rw-r--r--tools/libclang/libclang.exports1
6 files changed, 109 insertions, 5 deletions
diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py
index 5710d7fe28..cbce1a2d3f 100644
--- a/bindings/python/clang/cindex.py
+++ b/bindings/python/clang/cindex.py
@@ -1499,6 +1499,50 @@ TypeKind.VARIABLEARRAY = TypeKind(115)
TypeKind.DEPENDENTSIZEDARRAY = TypeKind(116)
TypeKind.MEMBERPOINTER = TypeKind(117)
+class RefQualifierKind(object):
+ """Describes a specific ref-qualifier of a type."""
+
+ # The unique kind objects, indexed by id.
+ _kinds = []
+ _name_map = None
+
+ def __init__(self, value):
+ if value >= len(RefQualifierKind._kinds):
+ num_kinds = value - len(RefQualifierKind._kinds) + 1
+ RefQualifierKind._kinds += [None] * num_kinds
+ if RefQualifierKind._kinds[value] is not None:
+ raise ValueError, 'RefQualifierKind already loaded'
+ self.value = value
+ RefQualifierKind._kinds[value] = self
+ RefQualifierKind._name_map = None
+
+ def from_param(self):
+ return self.value
+
+ @property
+ def name(self):
+ """Get the enumeration name of this kind."""
+ if self._name_map is None:
+ self._name_map = {}
+ for key, value in RefQualifierKind.__dict__.items():
+ if isinstance(value, RefQualifierKind):
+ self._name_map[value] = key
+ return self._name_map[self]
+
+ @staticmethod
+ def from_id(id):
+ if (id >= len(RefQualifierKind._kinds) or
+ RefQualifierKind._kinds[id] is None):
+ raise ValueError, 'Unknown type kind %d' % id
+ return RefQualifierKind._kinds[id]
+
+ def __repr__(self):
+ return 'RefQualifierKind.%s' % (self.name,)
+
+RefQualifierKind.NONE = RefQualifierKind(0)
+RefQualifierKind.LVALUE = RefQualifierKind(1)
+RefQualifierKind.RVALUE = RefQualifierKind(2)
+
class Type(Structure):
"""
The type of an element in the abstract syntax tree.
@@ -1697,6 +1741,13 @@ class Type(Structure):
"""
return conf.lib.clang_Type_getOffsetOf(self, c_char_p(fieldname))
+ def get_ref_qualifier(self):
+ """
+ Retrieve the ref-qualifier of the type.
+ """
+ return RefQualifierKind.from_id(
+ conf.lib.clang_Type_getCXXRefQualifier(self))
+
@property
def spelling(self):
"""Retrieve the spelling of this Type."""
@@ -2716,11 +2767,6 @@ functionList = [
[Type],
c_longlong),
- ("clang_Type_getClassType",
- [Type],
- Type,
- Type.from_result),
-
("clang_getFieldDeclBitWidth",
[Cursor],
c_int),
@@ -3164,6 +3210,11 @@ functionList = [
[Type],
c_longlong),
+ ("clang_Type_getClassType",
+ [Type],
+ Type,
+ Type.from_result),
+
("clang_Type_getOffsetOf",
[Type, c_char_p],
c_longlong),
@@ -3171,6 +3222,10 @@ functionList = [
("clang_Type_getSizeOf",
[Type],
c_longlong),
+
+ ("clang_Type_getCXXRefQualifier",
+ [Type],
+ c_uint),
]
class LibclangError(Exception):
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index ca0bc14eb2..c8cdcb7855 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -3002,6 +3002,23 @@ CINDEX_LINKAGE long long clang_Type_getSizeOf(CXType T);
*/
CINDEX_LINKAGE long long clang_Type_getOffsetOf(CXType T, const char *S);
+enum CXRefQualifierKind {
+ /** \brief No ref-qualifier was provided. */
+ CXRefQualifier_None = 0,
+ /** \brief An lvalue ref-qualifier was provided (\c &). */
+ CXRefQualifier_LValue,
+ /** \brief An rvalue ref-qualifier was provided (\c &&). */
+ CXRefQualifier_RValue
+};
+
+/**
+ * \brief Retrieve the ref-qualifier kind of a function or method.
+ *
+ * The ref-qualifier is returned for C++ functions or methods. For other types
+ * or non-C++ declarations, CXRefQualifier_None is returned.
+ */
+CINDEX_LINKAGE enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T);
+
/**
* \brief Returns non-zero if the cursor specifies a Record member that is a
* bitfield.
diff --git a/test/Index/print-type-cxx11.cpp b/test/Index/print-type-cxx11.cpp
new file mode 100644
index 0000000000..0ad5473774
--- /dev/null
+++ b/test/Index/print-type-cxx11.cpp
@@ -0,0 +1,8 @@
+struct RefQualifierTest {
+ void f() & {};
+ void f() && {};
+};
+
+// RUN: c-index-test -test-print-type -std=c++11 %s | FileCheck %s
+// CHECK: CXXMethod=f:2:8 (Definition) [type=void () &] [typekind=FunctionProto] lvalue-ref-qualifier [resulttype=void] [resulttypekind=Void] [isPOD=0]
+// CHECK: CXXMethod=f:3:8 (Definition) [type=void () &&] [typekind=FunctionProto] rvalue-ref-qualifier [resulttype=void] [resulttypekind=Void] [isPOD=0]
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index 2e8b58bff4..90a65282f4 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -1160,6 +1160,7 @@ static enum CXChildVisitResult PrintType(CXCursor cursor, CXCursor p,
CXClientData d) {
if (!clang_isInvalid(clang_getCursorKind(cursor))) {
CXType T = clang_getCursorType(cursor);
+ enum CXRefQualifierKind RQ = clang_Type_getCXXRefQualifier(T);
PrintCursor(cursor, NULL);
PrintTypeAndTypeKind(T, " [type=%s] [typekind=%s]");
if (clang_isConstQualifiedType(T))
@@ -1168,6 +1169,10 @@ static enum CXChildVisitResult PrintType(CXCursor cursor, CXCursor p,
printf(" volatile");
if (clang_isRestrictQualifiedType(T))
printf(" restrict");
+ if (RQ == CXRefQualifier_LValue)
+ printf(" lvalue-ref-qualifier");
+ if (RQ == CXRefQualifier_RValue)
+ printf(" rvalue-ref-qualifier");
/* Print the canonical type if it is different. */
{
CXType CT = clang_getCanonicalType(T);
diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp
index 9233e975f6..1e2cb18984 100644
--- a/tools/libclang/CXType.cpp
+++ b/tools/libclang/CXType.cpp
@@ -816,6 +816,24 @@ long long clang_Type_getOffsetOf(CXType PT, const char *S) {
return CXTypeLayoutError_InvalidFieldName;
}
+enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T) {
+ QualType QT = GetQualType(T);
+ if (QT.isNull())
+ return CXRefQualifier_None;
+ const FunctionProtoType *FD = QT->getAs<FunctionProtoType>();
+ if (!FD)
+ return CXRefQualifier_None;
+ switch (FD->getRefQualifier()) {
+ case RQ_None:
+ return CXRefQualifier_None;
+ case RQ_LValue:
+ return CXRefQualifier_LValue;
+ case RQ_RValue:
+ return CXRefQualifier_RValue;
+ }
+ return CXRefQualifier_None;
+}
+
unsigned clang_Cursor_isBitField(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return 0;
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index 6f6e39228d..9bf26c979d 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -64,6 +64,7 @@ clang_Type_getAlignOf
clang_Type_getClassType
clang_Type_getSizeOf
clang_Type_getOffsetOf
+clang_Type_getCXXRefQualifier
clang_VerbatimBlockLineComment_getText
clang_VerbatimLineComment_getText
clang_HTMLTagComment_getAsString