mirror of https://github.com/microsoft/clang.git
[libclang 4/8] Add the clang_Type_getNullability() API
Summary: This patch adds a clang-c API for querying the nullability of an AttributedType. The test here also tests D49081 Reviewers: yvvan, jbcoe Reviewed By: yvvan Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D49082 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@338809 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
57ac6fbcbf
commit
9824aedd2e
|
@ -3745,6 +3745,33 @@ CINDEX_LINKAGE CXType clang_Type_getNamedType(CXType T);
|
|||
*/
|
||||
CINDEX_LINKAGE unsigned clang_Type_isTransparentTagTypedef(CXType T);
|
||||
|
||||
enum CXTypeNullabilityKind {
|
||||
/**
|
||||
* Values of this type can never be null.
|
||||
*/
|
||||
CXTypeNullability_NonNull = 0,
|
||||
/**
|
||||
* Values of this type can be null.
|
||||
*/
|
||||
CXTypeNullability_Nullable = 1,
|
||||
/**
|
||||
* Whether values of this type can be null is (explicitly)
|
||||
* unspecified. This captures a (fairly rare) case where we
|
||||
* can't conclude anything about the nullability of the type even
|
||||
* though it has been considered.
|
||||
*/
|
||||
CXTypeNullability_Unspecified = 2,
|
||||
/**
|
||||
* Nullability is not applicable to this type.
|
||||
*/
|
||||
CXTypeNullability_Invalid = 3
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve the nullability kind of a pointer type.
|
||||
*/
|
||||
CINDEX_LINKAGE enum CXTypeNullabilityKind clang_Type_getNullability(CXType T);
|
||||
|
||||
/**
|
||||
* List the possible error codes for \c clang_Type_getSizeOf,
|
||||
* \c clang_Type_getAlignOf, \c clang_Type_getOffsetOf and
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
int *a;
|
||||
int * _Nonnull b;
|
||||
int * _Nullable c;
|
||||
int * _Null_unspecified d;
|
||||
|
||||
// RUN: env CINDEXTEST_INCLUDE_ATTRIBUTED_TYPES=1 c-index-test -test-print-type %s | FileCheck %s
|
||||
// CHECK: VarDecl=a:1:6 [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
|
||||
// CHECK: VarDecl=b:2:16 [type=int * _Nonnull] [typekind=Attributed] [nullability=nonnull] [canonicaltype=int *] [canonicaltypekind=Pointer] [modifiedtype=int *] [modifiedtypekind=Pointer] [isPOD=1]
|
||||
// CHECK: VarDecl=c:3:17 [type=int * _Nullable] [typekind=Attributed] [nullability=nullable] [canonicaltype=int *] [canonicaltypekind=Pointer] [modifiedtype=int *] [modifiedtypekind=Pointer] [isPOD=1]
|
||||
// CHECK: VarDecl=d:4:25 [type=int * _Null_unspecified] [typekind=Attributed] [nullability=unspecified] [canonicaltype=int *] [canonicaltypekind=Pointer] [modifiedtype=int *] [modifiedtypekind=Pointer] [isPOD=1]
|
|
@ -84,6 +84,8 @@ static unsigned getDefaultParsingOptions() {
|
|||
options |= CXTranslationUnit_KeepGoing;
|
||||
if (getenv("CINDEXTEST_LIMIT_SKIP_FUNCTION_BODIES_TO_PREAMBLE"))
|
||||
options |= CXTranslationUnit_LimitSkipFunctionBodiesToPreamble;
|
||||
if (getenv("CINDEXTEST_INCLUDE_ATTRIBUTED_TYPES"))
|
||||
options |= CXTranslationUnit_IncludeAttributedTypes;
|
||||
|
||||
return options;
|
||||
}
|
||||
|
@ -1496,6 +1498,22 @@ static void PrintTypeTemplateArgs(CXType T, const char *Format) {
|
|||
}
|
||||
}
|
||||
|
||||
static void PrintNullabilityKind(CXType T, const char *Format) {
|
||||
enum CXTypeNullabilityKind N = clang_Type_getNullability(T);
|
||||
|
||||
const char *nullability = 0;
|
||||
switch (N) {
|
||||
case CXTypeNullability_NonNull: nullability = "nonnull"; break;
|
||||
case CXTypeNullability_Nullable: nullability = "nullable"; break;
|
||||
case CXTypeNullability_Unspecified: nullability = "unspecified"; break;
|
||||
case CXTypeNullability_Invalid: break;
|
||||
}
|
||||
|
||||
if (nullability) {
|
||||
printf(Format, nullability);
|
||||
}
|
||||
}
|
||||
|
||||
static enum CXChildVisitResult PrintType(CXCursor cursor, CXCursor p,
|
||||
CXClientData d) {
|
||||
if (!clang_isInvalid(clang_getCursorKind(cursor))) {
|
||||
|
@ -1504,6 +1522,7 @@ static enum CXChildVisitResult PrintType(CXCursor cursor, CXCursor p,
|
|||
enum CXRefQualifierKind RQ = clang_Type_getCXXRefQualifier(T);
|
||||
PrintCursor(cursor, NULL);
|
||||
PrintTypeAndTypeKind(T, " [type=%s] [typekind=%s]");
|
||||
PrintNullabilityKind(T, " [nullability=%s]");
|
||||
if (clang_isConstQualifiedType(T))
|
||||
printf(" const");
|
||||
if (clang_isVolatileQualifiedType(T))
|
||||
|
@ -1524,12 +1543,20 @@ static enum CXChildVisitResult PrintType(CXCursor cursor, CXCursor p,
|
|||
PrintTypeTemplateArgs(CT, " [canonicaltemplateargs/%d=");
|
||||
}
|
||||
}
|
||||
/* Print the modified type if it exists. */
|
||||
{
|
||||
CXType MT = clang_Type_getModifiedType(T);
|
||||
if (MT.kind != CXType_Invalid) {
|
||||
PrintTypeAndTypeKind(MT, " [modifiedtype=%s] [modifiedtypekind=%s]");
|
||||
}
|
||||
}
|
||||
/* Print the return type if it exists. */
|
||||
{
|
||||
CXType RT = clang_getCursorResultType(cursor);
|
||||
if (RT.kind != CXType_Invalid) {
|
||||
PrintTypeAndTypeKind(RT, " [resulttype=%s] [resulttypekind=%s]");
|
||||
}
|
||||
PrintNullabilityKind(RT, " [resultnullability=%s]");
|
||||
}
|
||||
/* Print the argument types if they exist. */
|
||||
{
|
||||
|
@ -1541,6 +1568,7 @@ static enum CXChildVisitResult PrintType(CXCursor cursor, CXCursor p,
|
|||
CXType T = clang_getCursorType(clang_Cursor_getArgument(cursor, i));
|
||||
if (T.kind != CXType_Invalid) {
|
||||
PrintTypeAndTypeKind(T, " [%s] [%s]");
|
||||
PrintNullabilityKind(T, " [%s]");
|
||||
}
|
||||
}
|
||||
printf("]");
|
||||
|
|
|
@ -1240,3 +1240,22 @@ unsigned clang_Type_isTransparentTagTypedef(CXType TT){
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
enum CXTypeNullabilityKind clang_Type_getNullability(CXType CT) {
|
||||
QualType T = GetQualType(CT);
|
||||
if (T.isNull())
|
||||
return CXTypeNullability_Invalid;
|
||||
|
||||
ASTContext &Ctx = cxtu::getASTUnit(GetTU(CT))->getASTContext();
|
||||
if (auto nullability = T->getNullability(Ctx)) {
|
||||
switch (*nullability) {
|
||||
case NullabilityKind::NonNull:
|
||||
return CXTypeNullability_NonNull;
|
||||
case NullabilityKind::Nullable:
|
||||
return CXTypeNullability_Nullable;
|
||||
case NullabilityKind::Unspecified:
|
||||
return CXTypeNullability_Unspecified;
|
||||
}
|
||||
}
|
||||
return CXTypeNullability_Invalid;
|
||||
}
|
||||
|
|
|
@ -104,6 +104,7 @@ clang_Type_getObjCProtocolDecl
|
|||
clang_Type_getNumObjCTypeArgs
|
||||
clang_Type_getObjCTypeArg
|
||||
clang_Type_getModifiedType
|
||||
clang_Type_getNullability
|
||||
clang_VerbatimBlockLineComment_getText
|
||||
clang_VerbatimLineComment_getText
|
||||
clang_HTMLTagComment_getAsString
|
||||
|
|
Loading…
Reference in New Issue