[libclang] API enhancements by Joe Groff!

- Exposes a CXType_Vector type kind for vector types.
- Adds generalized versions of the clang_getArrayElementType and clang_getArraySize functions, named clang_getElementType and clang_getNumElements, which work on array, vector, or complex types.
- Adds additional functions for querying function types. clang_isFunctionTypeVariadic returns true if a function type is variadic. clang_getFunctionCallingConv returns an enumeration value indicating the calling convention of the function type. clang_getNumArgTypes returns the number of static argument types, and clang_getArgType gets the type of an argument.
- Adds a clang_getTypedefDeclUnderlyingType function to get the underlying type from a TypedefDecl cursor.
- Adds a clang_getEnumDeclIntegerType function to get the integer type from an EnumDecl cursor.
- Adds clang_getEnumConstantDeclValue and clang_getEnumConstantDeclUnsignedValue functions to get the value of an EnumConstantDecl as a signed or unsigned long long, respectively.
- Exposes a CXCursor_AsmLabelAttr cursor kind for __asm__("label") attributes.
- Alters clang_getCursorSpelling to return the label value for AsmLabelAttr-kind cursors.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145972 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp
index 0e62e27..8dcef4d 100644
--- a/tools/libclang/CXType.cpp
+++ b/tools/libclang/CXType.cpp
@@ -85,6 +85,7 @@
     TKCASE(FunctionNoProto);
     TKCASE(FunctionProto);
     TKCASE(ConstantArray);
+    TKCASE(Vector);
     default:
       return CXType_Unexposed;
   }
@@ -173,6 +174,74 @@
   return MakeCXType(QualType(), TU);
 }
 
+CXType clang_getTypedefDeclUnderlyingType(CXCursor C) {
+  using namespace cxcursor;
+  CXTranslationUnit TU = cxcursor::getCursorTU(C);
+
+  if (clang_isDeclaration(C.kind)) {
+    Decl *D = cxcursor::getCursorDecl(C);
+
+    if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
+      QualType T = TD->getUnderlyingType();
+      return MakeCXType(T, TU);
+    }
+
+    return MakeCXType(QualType(), TU);
+  }
+
+  return MakeCXType(QualType(), TU);
+}
+
+CXType clang_getEnumDeclIntegerType(CXCursor C) {
+  using namespace cxcursor;
+  CXTranslationUnit TU = cxcursor::getCursorTU(C);
+
+  if (clang_isDeclaration(C.kind)) {
+    Decl *D = cxcursor::getCursorDecl(C);
+
+    if (EnumDecl *TD = dyn_cast<EnumDecl>(D)) {
+      QualType T = TD->getIntegerType();
+      return MakeCXType(T, TU);
+    }
+
+    return MakeCXType(QualType(), TU);
+  }
+
+  return MakeCXType(QualType(), TU);
+}
+
+long long clang_getEnumConstantDeclValue(CXCursor C) {
+  using namespace cxcursor;
+
+  if (clang_isDeclaration(C.kind)) {
+    Decl *D = cxcursor::getCursorDecl(C);
+
+    if (EnumConstantDecl *TD = dyn_cast<EnumConstantDecl>(D)) {
+      return TD->getInitVal().getSExtValue();
+    }
+
+    return LLONG_MIN;
+  }
+
+  return LLONG_MIN;
+}
+
+unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C) {
+  using namespace cxcursor;
+
+  if (clang_isDeclaration(C.kind)) {
+    Decl *D = cxcursor::getCursorDecl(C);
+
+    if (EnumConstantDecl *TD = dyn_cast<EnumConstantDecl>(D)) {
+      return TD->getInitVal().getZExtValue();
+    }
+
+    return ULLONG_MAX;
+  }
+
+  return ULLONG_MAX;
+}
+
 CXType clang_getCanonicalType(CXType CT) {
   if (CT.kind == CXType_Invalid)
     return CT;
@@ -332,6 +401,7 @@
     TKIND(FunctionNoProto);
     TKIND(FunctionProto);
     TKIND(ConstantArray);
+    TKIND(Vector);
   }
 #undef TKIND
   return cxstring::createCXString(s);
@@ -341,9 +411,80 @@
   return A.data[0] == B.data[0] && A.data[1] == B.data[1];;
 }
 
+unsigned clang_isFunctionTypeVariadic(CXType X) {
+  QualType T = GetQualType(X);
+  if (T.isNull())
+    return 0;
+
+  if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>())
+    return (unsigned)FD->isVariadic();
+
+  if (T->getAs<FunctionNoProtoType>())
+    return 1;
+  
+  return 0;
+}
+
+CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
+  QualType T = GetQualType(X);
+  if (T.isNull())
+    return CXCallingConv_Invalid;
+  
+  if (const FunctionType *FD = T->getAs<FunctionType>()) {
+#define TCALLINGCONV(X) case CC_##X: return CXCallingConv_##X
+    switch (FD->getCallConv()) {
+      TCALLINGCONV(Default);
+      TCALLINGCONV(C);
+      TCALLINGCONV(X86StdCall);
+      TCALLINGCONV(X86FastCall);
+      TCALLINGCONV(X86ThisCall);
+      TCALLINGCONV(X86Pascal);
+      TCALLINGCONV(AAPCS);
+      TCALLINGCONV(AAPCS_VFP);
+    default:
+      return CXCallingConv_Unexposed;
+    }
+#undef TCALLINGCONV
+  }
+  
+  return CXCallingConv_Invalid;
+}
+
+unsigned clang_getNumArgTypes(CXType X) {
+  QualType T = GetQualType(X);
+  if (T.isNull())
+    return UINT_MAX;
+  
+  if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
+    return FD->getNumArgs();
+  }
+  
+  if (T->getAs<FunctionNoProtoType>()) {
+    return 0;
+  }
+  
+  return UINT_MAX;
+}
+
+CXType clang_getArgType(CXType X, unsigned i) {
+  QualType T = GetQualType(X);
+  if (T.isNull())
+    return MakeCXType(QualType(), GetTU(X));
+
+  if (const FunctionProtoType *FD = T->getAs<FunctionProtoType>()) {
+    unsigned numArgs = FD->getNumArgs();
+    if (i >= numArgs)
+      return MakeCXType(QualType(), GetTU(X));
+    
+    return MakeCXType(FD->getArgType(i), GetTU(X));
+  }
+  
+  return MakeCXType(QualType(), GetTU(X));
+}
+
 CXType clang_getResultType(CXType X) {
   QualType T = GetQualType(X);
-  if (!T.getTypePtrOrNull())
+  if (T.isNull())
     return MakeCXType(QualType(), GetTU(X));
   
   if (const FunctionType *FD = T->getAs<FunctionType>())
@@ -366,7 +507,7 @@
 
 unsigned clang_isPODType(CXType X) {
   QualType T = GetQualType(X);
-  if (!T.getTypePtrOrNull())
+  if (T.isNull())
     return 0;
   
   CXTranslationUnit TU = GetTU(X);
@@ -375,6 +516,49 @@
   return T.isPODType(AU->getASTContext()) ? 1 : 0;
 }
 
+CXType clang_getElementType(CXType CT) {
+  QualType ET = QualType();
+  QualType T = GetQualType(CT);
+  const Type *TP = T.getTypePtrOrNull();
+
+  if (TP) {
+    switch (TP->getTypeClass()) {
+    case Type::ConstantArray:
+      ET = cast<ConstantArrayType> (TP)->getElementType();
+      break;
+    case Type::Vector:
+      ET = cast<VectorType> (TP)->getElementType();
+      break;
+    case Type::Complex:
+      ET = cast<ComplexType> (TP)->getElementType();
+      break;
+    default:
+      break;
+    }
+  }
+  return MakeCXType(ET, GetTU(CT));
+}
+
+long long clang_getNumElements(CXType CT) {
+  long long result = -1;
+  QualType T = GetQualType(CT);
+  const Type *TP = T.getTypePtrOrNull();
+
+  if (TP) {
+    switch (TP->getTypeClass()) {
+    case Type::ConstantArray:
+      result = cast<ConstantArrayType> (TP)->getSize().getSExtValue();
+      break;
+    case Type::Vector:
+      result = cast<VectorType> (TP)->getNumElements();
+      break;
+    default:
+      break;
+    }
+  }
+  return result;
+}
+
 CXType clang_getArrayElementType(CXType CT) {
   QualType ET = QualType();
   QualType T = GetQualType(CT);