diff options
Diffstat (limited to 'clang/tools/libclang/CIndex.cpp')
| -rw-r--r-- | clang/tools/libclang/CIndex.cpp | 323 |
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; } |

