summaryrefslogtreecommitdiffstats
path: root/clang/tools/libclang/CIndex.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/tools/libclang/CIndex.cpp')
-rw-r--r--clang/tools/libclang/CIndex.cpp323
1 files changed, 323 insertions, 0 deletions
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index d57dd933072..18851a0dd8b 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -3289,6 +3289,329 @@ enum CXErrorCode clang_parseTranslationUnit2FullArgv(
return result;
}
+CXString clang_Type_getObjCEncoding(CXType CT) {
+ CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
+ ASTContext &Ctx = getASTUnit(tu)->getASTContext();
+ std::string encoding;
+ Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]),
+ encoding);
+
+ return cxstring::createDup(encoding);
+}
+
+static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
+ if (C.kind == CXCursor_MacroDefinition) {
+ if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
+ return MDR->getName();
+ } else if (C.kind == CXCursor_MacroExpansion) {
+ MacroExpansionCursor ME = getCursorMacroExpansion(C);
+ return ME.getName();
+ }
+ return nullptr;
+}
+
+unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
+ const IdentifierInfo *II = getMacroIdentifier(C);
+ if (!II) {
+ return false;
+ }
+ ASTUnit *ASTU = getCursorASTUnit(C);
+ Preprocessor &PP = ASTU->getPreprocessor();
+ if (const MacroInfo *MI = PP.getMacroInfo(II))
+ return MI->isFunctionLike();
+ return false;
+}
+
+unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
+ const IdentifierInfo *II = getMacroIdentifier(C);
+ if (!II) {
+ return false;
+ }
+ ASTUnit *ASTU = getCursorASTUnit(C);
+ Preprocessor &PP = ASTU->getPreprocessor();
+ if (const MacroInfo *MI = PP.getMacroInfo(II))
+ return MI->isBuiltinMacro();
+ return false;
+}
+
+unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
+ const Decl *D = getCursorDecl(C);
+ const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
+ if (!FD) {
+ return false;
+ }
+ return FD->isInlined();
+}
+
+static StringLiteral* getCFSTR_value(CallExpr *callExpr) {
+ if (callExpr->getNumArgs() != 1) {
+ return nullptr;
+ }
+
+ StringLiteral *S = nullptr;
+ auto *arg = callExpr->getArg(0);
+ if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
+ ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
+ auto *subExpr = I->getSubExprAsWritten();
+
+ if(subExpr->getStmtClass() != Stmt::StringLiteralClass){
+ return nullptr;
+ }
+
+ S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
+ } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
+ S = static_cast<StringLiteral *>(callExpr->getArg(0));
+ } else {
+ return nullptr;
+ }
+ return S;
+}
+
+typedef struct {
+ CXEvalResultKind EvalType;
+ union {
+ int intVal;
+ double floatVal;
+ char *stringVal;
+ } EvalData;
+} ExprEvalResult;
+
+void clang_EvalResult_dispose(CXEvalResult E) {
+ ExprEvalResult *ER = (ExprEvalResult *)E;
+ if (ER) {
+ CXEvalResultKind evalType = ER->EvalType;
+
+ if (evalType != CXEval_UnExposed && evalType != CXEval_Float &&
+ evalType != CXEval_Int && ER->EvalData.stringVal) {
+ free((void *) ER->EvalData.stringVal);
+ }
+ free((void *)ER);
+ }
+}
+
+CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
+ if (!E) {
+ return CXEval_UnExposed;
+ }
+ return ((ExprEvalResult *)E)->EvalType;
+}
+
+int clang_EvalResult_getAsInt(CXEvalResult E) {
+ if (!E) {
+ return 0;
+ }
+ return ((ExprEvalResult *)E)->EvalData.intVal;
+}
+
+double clang_EvalResult_getAsDouble(CXEvalResult E) {
+ if (!E) {
+ return 0;
+ }
+ return ((ExprEvalResult *)E)->EvalData.floatVal;
+}
+
+const char* clang_EvalResult_getAsStr(CXEvalResult E) {
+ if (!E) {
+ return nullptr;
+ }
+ return ((ExprEvalResult *)E)->EvalData.stringVal;
+}
+
+static const ExprEvalResult* evaluateExpr(Expr *expr, CXCursor C) {
+ Expr::EvalResult ER;
+ ASTContext &ctx = getCursorContext(C);
+ if (!expr) {
+ return nullptr;
+ }
+ expr = expr->IgnoreParens();
+ bool res = expr->EvaluateAsRValue(ER, ctx);
+ QualType rettype;
+ CallExpr *callExpr;
+ ExprEvalResult *result = (ExprEvalResult *) malloc(sizeof(ExprEvalResult));
+ if (!result) {
+ return nullptr;
+ }
+ result->EvalType = CXEval_UnExposed;
+
+ if (res) {
+
+ if (ER.Val.isInt()) {
+ result->EvalType = CXEval_Int;
+ result->EvalData.intVal = ER.Val.getInt().getExtValue();
+ return result;
+ } else if (ER.Val.isFloat()) {
+
+ llvm::SmallVector<char, 100> Buffer;
+ ER.Val.getFloat().toString(Buffer);
+ std::string floatStr(Buffer.data(), Buffer.size());
+ result->EvalType = CXEval_Float;
+ bool ignored;
+ llvm::APFloat apFloat = ER.Val.getFloat();
+ apFloat.convert(llvm::APFloat::IEEEdouble,
+ llvm::APFloat::rmNearestTiesToEven, &ignored);
+ result->EvalData.floatVal = apFloat.convertToDouble();
+ return result;
+
+ } else if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
+
+ const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
+ auto *subExpr = I->getSubExprAsWritten();
+ if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
+ subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
+
+ const StringLiteral *StrE = nullptr;
+ const ObjCStringLiteral *ObjCExpr;
+ ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);
+
+ if (ObjCExpr) {
+ StrE = ObjCExpr->getString();
+ result->EvalType = CXEval_ObjCStrLiteral;
+ } else {
+ StrE = cast<StringLiteral>(I->getSubExprAsWritten());
+ result->EvalType = CXEval_StrLiteral;
+ }
+
+ std::string strRef(StrE->getString().str());
+ result->EvalData.stringVal = (char *)malloc(strRef.size()+1);
+ strncpy((char*)result->EvalData.stringVal, strRef.c_str(),
+ strRef.size());
+ result->EvalData.stringVal[strRef.size()] = '\0';
+ return result;
+ }
+
+ } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
+ expr->getStmtClass() == Stmt::StringLiteralClass) {
+
+ const StringLiteral *StrE = nullptr;
+ const ObjCStringLiteral *ObjCExpr;
+ ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);
+
+ if (ObjCExpr) {
+ StrE = ObjCExpr->getString();
+ result->EvalType = CXEval_ObjCStrLiteral;
+ } else {
+ StrE = cast<StringLiteral>(expr);
+ result->EvalType = CXEval_StrLiteral;
+ }
+
+ std::string strRef(StrE->getString().str());
+ result->EvalData.stringVal = (char *)malloc(strRef.size()+1);
+ strncpy((char*)result->EvalData.stringVal, strRef.c_str(),
+ strRef.size());
+ result->EvalData.stringVal[strRef.size()] = '\0';
+ return result;
+
+ } else if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
+
+ CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);
+
+ rettype = CC->getType();
+ if (rettype.getAsString() == "CFStringRef" &&
+ CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {
+
+ callExpr = static_cast<CallExpr *>(CC->getSubExpr());
+ StringLiteral* S = getCFSTR_value(callExpr);
+ if (S) {
+ std::string strLiteral(S->getString().str());
+ result->EvalType = CXEval_CFStr;
+
+ result->EvalData.stringVal = (char *)malloc(strLiteral.size()+1);
+ strncpy((char*)result->EvalData.stringVal, strLiteral.c_str(),
+ strLiteral.size());
+ result->EvalData.stringVal[strLiteral.size()] = '\0';
+ return result;
+ }
+ }
+
+ } else if (expr->getStmtClass() == Stmt::CallExprClass) {
+
+ callExpr = static_cast<CallExpr *>(expr);
+ rettype = callExpr->getCallReturnType(ctx);
+
+ if (rettype->isVectorType() || callExpr->getNumArgs() > 1) {
+ return nullptr;
+ }
+ if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
+ if(callExpr->getNumArgs() == 1 &&
+ !callExpr->getArg(0)->getType()->isIntegralType(ctx)){
+
+ return nullptr;
+ }
+ } else if(rettype.getAsString() == "CFStringRef") {
+
+ StringLiteral* S = getCFSTR_value(callExpr);
+ if (S) {
+ std::string strLiteral(S->getString().str());
+ result->EvalType = CXEval_CFStr;
+ result->EvalData.stringVal = (char *)malloc(strLiteral.size()+1);
+ strncpy((char*)result->EvalData.stringVal, strLiteral.c_str(),
+ strLiteral.size());
+ result->EvalData.stringVal[strLiteral.size()] = '\0';
+ return result;
+ }
+ }
+
+ } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
+
+ DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
+ ValueDecl *V = D->getDecl();
+ if (V->getKind() == Decl::Function) {
+ std::string strName(V->getNameAsString());
+ result->EvalType = CXEval_Other;
+ result->EvalData.stringVal = (char *)malloc(strName.size()+1);
+ strncpy((char*)result->EvalData.stringVal, strName.c_str(),
+ strName.size());
+ result->EvalData.stringVal[strName.size()] = '\0';
+ return result;
+ }
+ }
+
+ }
+
+ clang_EvalResult_dispose((CXEvalResult *)result);
+ return nullptr;
+}
+
+CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
+ const Decl *D = getCursorDecl(C);
+ if (D) {
+ const Expr *expr = nullptr;
+ if (auto *Var = dyn_cast<VarDecl>(D)) {
+ expr = Var->getInit();
+ } else if (auto *Field = dyn_cast<FieldDecl>(D)) {
+ expr = Field->getInClassInitializer();
+ }
+ if (expr)
+ return (CXEvalResult)evaluateExpr((Expr *)expr, C);
+ return nullptr;
+ }
+
+ const CompoundStmt *compoundStmt = dyn_cast_or_null<CompoundStmt>(getCursorStmt(C));
+ if (compoundStmt) {
+ Expr *expr = nullptr;
+ for (auto *bodyIterator : compoundStmt->body()) {
+ if ((expr = dyn_cast<Expr>(bodyIterator))) {
+ break;
+ }
+ }
+ if (expr)
+ return (CXEvalResult)evaluateExpr(expr, C);
+ }
+ return nullptr;
+}
+
+unsigned clang_Cursor_hasAttrs(CXCursor C) {
+ const Decl *D = getCursorDecl(C);
+ if (!D) {
+ return 0;
+ }
+
+ if (D->hasAttrs()) {
+ return 1;
+ }
+
+ return 0;
+}
unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
return CXSaveTranslationUnit_None;
}
OpenPOWER on IntegriCloud