ClangASTContext.cpp revision eae91241c959357e5e867cfb257e762574b68dd6
1cfd74d65d832137e20e193c960802afba73b5d38sm//===-- ClangASTContext.cpp -------------------------------------*- C++ -*-===// 23c1e67e433728684b5f228c5d4f3e5b1457bb271sm// 3cfd74d65d832137e20e193c960802afba73b5d38sm// The LLVM Compiler Infrastructure 4cfd74d65d832137e20e193c960802afba73b5d38sm// 5cfd74d65d832137e20e193c960802afba73b5d38sm// This file is distributed under the University of Illinois Open Source 6cfd74d65d832137e20e193c960802afba73b5d38sm// License. See LICENSE.TXT for details. 7cfd74d65d832137e20e193c960802afba73b5d38sm// 8cfd74d65d832137e20e193c960802afba73b5d38sm//===----------------------------------------------------------------------===// 9cfd74d65d832137e20e193c960802afba73b5d38sm 10cfd74d65d832137e20e193c960802afba73b5d38sm#include "lldb/Symbol/ClangASTContext.h" 11cfd74d65d832137e20e193c960802afba73b5d38sm 12cfd74d65d832137e20e193c960802afba73b5d38sm// C Includes 13cfd74d65d832137e20e193c960802afba73b5d38sm// C++ Includes 14cfd74d65d832137e20e193c960802afba73b5d38sm#include <string> 15cfd74d65d832137e20e193c960802afba73b5d38sm 16cfd74d65d832137e20e193c960802afba73b5d38sm// Other libraries and framework includes 17cfd74d65d832137e20e193c960802afba73b5d38sm#define NDEBUG 18cfd74d65d832137e20e193c960802afba73b5d38sm#include "clang/AST/ASTContext.h" 19cfd74d65d832137e20e193c960802afba73b5d38sm#include "clang/AST/ASTImporter.h" 202b1168acefb6a4104bb7f008df6ac51fcd1de7ecsm#include "clang/AST/CXXInheritance.h" 212b1168acefb6a4104bb7f008df6ac51fcd1de7ecsm#include "clang/AST/DeclObjC.h" 22cfd74d65d832137e20e193c960802afba73b5d38sm#include "clang/AST/RecordLayout.h" 23cfd74d65d832137e20e193c960802afba73b5d38sm#include "clang/AST/Type.h" 24cfd74d65d832137e20e193c960802afba73b5d38sm#include "clang/Basic/Builtins.h" 25cfd74d65d832137e20e193c960802afba73b5d38sm#include "clang/Basic/FileManager.h" 26cfd74d65d832137e20e193c960802afba73b5d38sm#include "clang/Basic/FileSystemOptions.h" 27cfd74d65d832137e20e193c960802afba73b5d38sm#include "clang/Basic/SourceManager.h" 28cfd74d65d832137e20e193c960802afba73b5d38sm#include "clang/Basic/TargetInfo.h" 29cfd74d65d832137e20e193c960802afba73b5d38sm#include "clang/Basic/TargetOptions.h" 30cfd74d65d832137e20e193c960802afba73b5d38sm#include "clang/Frontend/FrontendOptions.h" 31cfd74d65d832137e20e193c960802afba73b5d38sm#include "clang/Frontend/LangStandard.h" 32cfd74d65d832137e20e193c960802afba73b5d38sm#undef NDEBUG 33cfd74d65d832137e20e193c960802afba73b5d38sm 34cfd74d65d832137e20e193c960802afba73b5d38sm#include "lldb/Core/dwarf.h" 35cfd74d65d832137e20e193c960802afba73b5d38sm#include "lldb/Core/Flags.h" 36cfd74d65d832137e20e193c960802afba73b5d38sm#include "lldb/Core/Log.h" 37cfd74d65d832137e20e193c960802afba73b5d38sm 38cfd74d65d832137e20e193c960802afba73b5d38sm#include <stdio.h> 39cfd74d65d832137e20e193c960802afba73b5d38sm 40cfd74d65d832137e20e193c960802afba73b5d38smusing namespace lldb; 41cfd74d65d832137e20e193c960802afba73b5d38smusing namespace lldb_private; 42cfd74d65d832137e20e193c960802afba73b5d38smusing namespace llvm; 43cfd74d65d832137e20e193c960802afba73b5d38smusing namespace clang; 44cfd74d65d832137e20e193c960802afba73b5d38sm 45cfd74d65d832137e20e193c960802afba73b5d38smstatic AccessSpecifier 46cfd74d65d832137e20e193c960802afba73b5d38smConvertAccessTypeToAccessSpecifier (AccessType access) 47cfd74d65d832137e20e193c960802afba73b5d38sm{ 48cfd74d65d832137e20e193c960802afba73b5d38sm switch (access) 49cfd74d65d832137e20e193c960802afba73b5d38sm { 50cfd74d65d832137e20e193c960802afba73b5d38sm default: break; 51cfd74d65d832137e20e193c960802afba73b5d38sm case eAccessNone: return AS_none; 52cfd74d65d832137e20e193c960802afba73b5d38sm case eAccessPublic: return AS_public; 53cfd74d65d832137e20e193c960802afba73b5d38sm case eAccessPrivate: return AS_private; 542b1168acefb6a4104bb7f008df6ac51fcd1de7ecsm case eAccessProtected: return AS_protected; 552b1168acefb6a4104bb7f008df6ac51fcd1de7ecsm } 562b1168acefb6a4104bb7f008df6ac51fcd1de7ecsm return AS_none; 572b1168acefb6a4104bb7f008df6ac51fcd1de7ecsm} 582b1168acefb6a4104bb7f008df6ac51fcd1de7ecsm 592b1168acefb6a4104bb7f008df6ac51fcd1de7ecsmstatic ObjCIvarDecl::AccessControl 602b1168acefb6a4104bb7f008df6ac51fcd1de7ecsmConvertAccessTypeToObjCIvarAccessControl (AccessType access) 612b1168acefb6a4104bb7f008df6ac51fcd1de7ecsm{ 622b1168acefb6a4104bb7f008df6ac51fcd1de7ecsm switch (access) 63cfd74d65d832137e20e193c960802afba73b5d38sm { 64cfd74d65d832137e20e193c960802afba73b5d38sm default: break; 65cfd74d65d832137e20e193c960802afba73b5d38sm case eAccessNone: return ObjCIvarDecl::None; 66cfd74d65d832137e20e193c960802afba73b5d38sm case eAccessPublic: return ObjCIvarDecl::Public; 67cfd74d65d832137e20e193c960802afba73b5d38sm case eAccessPrivate: return ObjCIvarDecl::Private; 68cfd74d65d832137e20e193c960802afba73b5d38sm case eAccessProtected: return ObjCIvarDecl::Protected; 69cfd74d65d832137e20e193c960802afba73b5d38sm case eAccessPackage: return ObjCIvarDecl::Package; 70cfd74d65d832137e20e193c960802afba73b5d38sm } 71cfd74d65d832137e20e193c960802afba73b5d38sm return ObjCIvarDecl::None; 72cfd74d65d832137e20e193c960802afba73b5d38sm} 73cfd74d65d832137e20e193c960802afba73b5d38sm 74cfd74d65d832137e20e193c960802afba73b5d38sm 75cfd74d65d832137e20e193c960802afba73b5d38smstatic void 76cfd74d65d832137e20e193c960802afba73b5d38smParseLangArgs 77cfd74d65d832137e20e193c960802afba73b5d38sm( 78cfd74d65d832137e20e193c960802afba73b5d38sm LangOptions &Opts, 79cfd74d65d832137e20e193c960802afba73b5d38sm InputKind IK 80cfd74d65d832137e20e193c960802afba73b5d38sm) 81cfd74d65d832137e20e193c960802afba73b5d38sm{ 82cfd74d65d832137e20e193c960802afba73b5d38sm // FIXME: Cleanup per-file based stuff. 83cfd74d65d832137e20e193c960802afba73b5d38sm 84cfd74d65d832137e20e193c960802afba73b5d38sm // Set some properties which depend soley on the input kind; it would be nice 85cfd74d65d832137e20e193c960802afba73b5d38sm // to move these to the language standard, and have the driver resolve the 86cfd74d65d832137e20e193c960802afba73b5d38sm // input kind + language standard. 87cfd74d65d832137e20e193c960802afba73b5d38sm if (IK == IK_Asm) { 88cfd74d65d832137e20e193c960802afba73b5d38sm Opts.AsmPreprocessor = 1; 89cfd74d65d832137e20e193c960802afba73b5d38sm } else if (IK == IK_ObjC || 90cfd74d65d832137e20e193c960802afba73b5d38sm IK == IK_ObjCXX || 91cfd74d65d832137e20e193c960802afba73b5d38sm IK == IK_PreprocessedObjC || 92cfd74d65d832137e20e193c960802afba73b5d38sm IK == IK_PreprocessedObjCXX) { 93cfd74d65d832137e20e193c960802afba73b5d38sm Opts.ObjC1 = Opts.ObjC2 = 1; 94cfd74d65d832137e20e193c960802afba73b5d38sm } 95cfd74d65d832137e20e193c960802afba73b5d38sm 96cfd74d65d832137e20e193c960802afba73b5d38sm LangStandard::Kind LangStd = LangStandard::lang_unspecified; 97cfd74d65d832137e20e193c960802afba73b5d38sm 98cfd74d65d832137e20e193c960802afba73b5d38sm if (LangStd == LangStandard::lang_unspecified) { 99cfd74d65d832137e20e193c960802afba73b5d38sm // Based on the base language, pick one. 100cfd74d65d832137e20e193c960802afba73b5d38sm switch (IK) { 101cfd74d65d832137e20e193c960802afba73b5d38sm case IK_None: 102cfd74d65d832137e20e193c960802afba73b5d38sm case IK_AST: 103cfd74d65d832137e20e193c960802afba73b5d38sm assert(0 && "Invalid input kind!"); 104cfd74d65d832137e20e193c960802afba73b5d38sm case IK_OpenCL: 105cfd74d65d832137e20e193c960802afba73b5d38sm LangStd = LangStandard::lang_opencl; 106cfd74d65d832137e20e193c960802afba73b5d38sm break; 107cfd74d65d832137e20e193c960802afba73b5d38sm case IK_Asm: 108cfd74d65d832137e20e193c960802afba73b5d38sm case IK_C: 109cfd74d65d832137e20e193c960802afba73b5d38sm case IK_PreprocessedC: 110cfd74d65d832137e20e193c960802afba73b5d38sm case IK_ObjC: 111cfd74d65d832137e20e193c960802afba73b5d38sm case IK_PreprocessedObjC: 112cfd74d65d832137e20e193c960802afba73b5d38sm LangStd = LangStandard::lang_gnu99; 113cfd74d65d832137e20e193c960802afba73b5d38sm break; 114cfd74d65d832137e20e193c960802afba73b5d38sm case IK_CXX: 115cfd74d65d832137e20e193c960802afba73b5d38sm case IK_PreprocessedCXX: 116cfd74d65d832137e20e193c960802afba73b5d38sm case IK_ObjCXX: 117cfd74d65d832137e20e193c960802afba73b5d38sm case IK_PreprocessedObjCXX: 118cfd74d65d832137e20e193c960802afba73b5d38sm LangStd = LangStandard::lang_gnucxx98; 119cfd74d65d832137e20e193c960802afba73b5d38sm break; 120cfd74d65d832137e20e193c960802afba73b5d38sm } 121cfd74d65d832137e20e193c960802afba73b5d38sm } 122cfd74d65d832137e20e193c960802afba73b5d38sm 123cfd74d65d832137e20e193c960802afba73b5d38sm const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd); 124cfd74d65d832137e20e193c960802afba73b5d38sm Opts.BCPLComment = Std.hasBCPLComments(); 125cfd74d65d832137e20e193c960802afba73b5d38sm Opts.C99 = Std.isC99(); 126cfd74d65d832137e20e193c960802afba73b5d38sm Opts.CPlusPlus = Std.isCPlusPlus(); 127cfd74d65d832137e20e193c960802afba73b5d38sm Opts.CPlusPlus0x = Std.isCPlusPlus0x(); 128cfd74d65d832137e20e193c960802afba73b5d38sm Opts.Digraphs = Std.hasDigraphs(); 129cfd74d65d832137e20e193c960802afba73b5d38sm Opts.GNUMode = Std.isGNUMode(); 130cfd74d65d832137e20e193c960802afba73b5d38sm Opts.GNUInline = !Std.isC99(); 131cfd74d65d832137e20e193c960802afba73b5d38sm Opts.HexFloats = Std.hasHexFloats(); 132cfd74d65d832137e20e193c960802afba73b5d38sm Opts.ImplicitInt = Std.hasImplicitInt(); 133cfd74d65d832137e20e193c960802afba73b5d38sm 134cfd74d65d832137e20e193c960802afba73b5d38sm // OpenCL has some additional defaults. 135cfd74d65d832137e20e193c960802afba73b5d38sm if (LangStd == LangStandard::lang_opencl) { 136cfd74d65d832137e20e193c960802afba73b5d38sm Opts.OpenCL = 1; 137cfd74d65d832137e20e193c960802afba73b5d38sm Opts.AltiVec = 1; 138cfd74d65d832137e20e193c960802afba73b5d38sm Opts.CXXOperatorNames = 1; 139cfd74d65d832137e20e193c960802afba73b5d38sm Opts.LaxVectorConversions = 1; 140cfd74d65d832137e20e193c960802afba73b5d38sm } 141cfd74d65d832137e20e193c960802afba73b5d38sm 142cfd74d65d832137e20e193c960802afba73b5d38sm // OpenCL and C++ both have bool, true, false keywords. 143cfd74d65d832137e20e193c960802afba73b5d38sm Opts.Bool = Opts.OpenCL || Opts.CPlusPlus; 144cfd74d65d832137e20e193c960802afba73b5d38sm 145cfd74d65d832137e20e193c960802afba73b5d38sm// if (Opts.CPlusPlus) 146cfd74d65d832137e20e193c960802afba73b5d38sm// Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names); 147cfd74d65d832137e20e193c960802afba73b5d38sm// 148cfd74d65d832137e20e193c960802afba73b5d38sm// if (Args.hasArg(OPT_fobjc_gc_only)) 149cfd74d65d832137e20e193c960802afba73b5d38sm// Opts.setGCMode(LangOptions::GCOnly); 150cfd74d65d832137e20e193c960802afba73b5d38sm// else if (Args.hasArg(OPT_fobjc_gc)) 1512b1168acefb6a4104bb7f008df6ac51fcd1de7ecsm// Opts.setGCMode(LangOptions::HybridGC); 1522b1168acefb6a4104bb7f008df6ac51fcd1de7ecsm// 1532b1168acefb6a4104bb7f008df6ac51fcd1de7ecsm// if (Args.hasArg(OPT_print_ivar_layout)) 154cfd74d65d832137e20e193c960802afba73b5d38sm// Opts.ObjCGCBitmapPrint = 1; 155cfd74d65d832137e20e193c960802afba73b5d38sm// 156cfd74d65d832137e20e193c960802afba73b5d38sm// if (Args.hasArg(OPT_faltivec)) 157cfd74d65d832137e20e193c960802afba73b5d38sm// Opts.AltiVec = 1; 158cfd74d65d832137e20e193c960802afba73b5d38sm// 159cfd74d65d832137e20e193c960802afba73b5d38sm// if (Args.hasArg(OPT_pthread)) 160cfd74d65d832137e20e193c960802afba73b5d38sm// Opts.POSIXThreads = 1; 161cfd74d65d832137e20e193c960802afba73b5d38sm// 162cfd74d65d832137e20e193c960802afba73b5d38sm// llvm::StringRef Vis = getLastArgValue(Args, OPT_fvisibility, 163cfd74d65d832137e20e193c960802afba73b5d38sm// "default"); 164cfd74d65d832137e20e193c960802afba73b5d38sm// if (Vis == "default") 165cfd74d65d832137e20e193c960802afba73b5d38sm Opts.setVisibilityMode(DefaultVisibility); 166cfd74d65d832137e20e193c960802afba73b5d38sm// else if (Vis == "hidden") 167cfd74d65d832137e20e193c960802afba73b5d38sm// Opts.setVisibilityMode(LangOptions::Hidden); 168cfd74d65d832137e20e193c960802afba73b5d38sm// else if (Vis == "protected") 169cfd74d65d832137e20e193c960802afba73b5d38sm// Opts.setVisibilityMode(LangOptions::Protected); 170cfd74d65d832137e20e193c960802afba73b5d38sm// else 171cfd74d65d832137e20e193c960802afba73b5d38sm// Diags.Report(diag::err_drv_invalid_value) 172cfd74d65d832137e20e193c960802afba73b5d38sm// << Args.getLastArg(OPT_fvisibility)->getAsString(Args) << Vis; 173cfd74d65d832137e20e193c960802afba73b5d38sm 174cfd74d65d832137e20e193c960802afba73b5d38sm// Opts.OverflowChecking = Args.hasArg(OPT_ftrapv); 175cfd74d65d832137e20e193c960802afba73b5d38sm 176cfd74d65d832137e20e193c960802afba73b5d38sm // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs 177cfd74d65d832137e20e193c960802afba73b5d38sm // is specified, or -std is set to a conforming mode. 178cfd74d65d832137e20e193c960802afba73b5d38sm Opts.Trigraphs = !Opts.GNUMode; 179cfd74d65d832137e20e193c960802afba73b5d38sm// if (Args.hasArg(OPT_trigraphs)) 180// Opts.Trigraphs = 1; 181// 182// Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers, 183// OPT_fno_dollars_in_identifiers, 184// !Opts.AsmPreprocessor); 185// Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings); 186// Opts.Microsoft = Args.hasArg(OPT_fms_extensions); 187// Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings); 188// if (Args.hasArg(OPT_fno_lax_vector_conversions)) 189// Opts.LaxVectorConversions = 0; 190// Opts.Exceptions = Args.hasArg(OPT_fexceptions); 191// Opts.RTTI = !Args.hasArg(OPT_fno_rtti); 192// Opts.Blocks = Args.hasArg(OPT_fblocks); 193// Opts.CharIsSigned = !Args.hasArg(OPT_fno_signed_char); 194// Opts.ShortWChar = Args.hasArg(OPT_fshort_wchar); 195// Opts.Freestanding = Args.hasArg(OPT_ffreestanding); 196// Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding; 197// Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new); 198// Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions); 199// Opts.AccessControl = Args.hasArg(OPT_faccess_control); 200// Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors); 201// Opts.MathErrno = !Args.hasArg(OPT_fno_math_errno); 202// Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99, 203// Diags); 204// Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime); 205// Opts.ObjCConstantStringClass = getLastArgValue(Args, 206// OPT_fconstant_string_class); 207// Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi); 208// Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior); 209// Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls); 210// Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags); 211// Opts.Static = Args.hasArg(OPT_static_define); 212 Opts.OptimizeSize = 0; 213 214 // FIXME: Eliminate this dependency. 215// unsigned Opt = 216// Args.hasArg(OPT_Os) ? 2 : getLastArgIntValue(Args, OPT_O, 0, Diags); 217// Opts.Optimize = Opt != 0; 218 unsigned Opt = 0; 219 220 // This is the __NO_INLINE__ define, which just depends on things like the 221 // optimization level and -fno-inline, not actually whether the backend has 222 // inlining enabled. 223 // 224 // FIXME: This is affected by other options (-fno-inline). 225 Opts.NoInline = !Opt; 226 227// unsigned SSP = getLastArgIntValue(Args, OPT_stack_protector, 0, Diags); 228// switch (SSP) { 229// default: 230// Diags.Report(diag::err_drv_invalid_value) 231// << Args.getLastArg(OPT_stack_protector)->getAsString(Args) << SSP; 232// break; 233// case 0: Opts.setStackProtectorMode(LangOptions::SSPOff); break; 234// case 1: Opts.setStackProtectorMode(LangOptions::SSPOn); break; 235// case 2: Opts.setStackProtectorMode(LangOptions::SSPReq); break; 236// } 237} 238 239 240ClangASTContext::ClangASTContext(const char *target_triple) : 241 m_target_triple(), 242 m_ast_context_ap(), 243 m_language_options_ap(), 244 m_source_manager_ap(), 245 m_diagnostic_ap(), 246 m_target_options_ap(), 247 m_target_info_ap(), 248 m_identifier_table_ap(), 249 m_selector_table_ap(), 250 m_builtins_ap() 251{ 252 if (target_triple && target_triple[0]) 253 m_target_triple.assign (target_triple); 254} 255 256//---------------------------------------------------------------------- 257// Destructor 258//---------------------------------------------------------------------- 259ClangASTContext::~ClangASTContext() 260{ 261 m_builtins_ap.reset(); 262 m_selector_table_ap.reset(); 263 m_identifier_table_ap.reset(); 264 m_target_info_ap.reset(); 265 m_target_options_ap.reset(); 266 m_diagnostic_ap.reset(); 267 m_source_manager_ap.reset(); 268 m_language_options_ap.reset(); 269 m_ast_context_ap.reset(); 270} 271 272 273void 274ClangASTContext::Clear() 275{ 276 m_ast_context_ap.reset(); 277 m_language_options_ap.reset(); 278 m_source_manager_ap.reset(); 279 m_diagnostic_ap.reset(); 280 m_target_options_ap.reset(); 281 m_target_info_ap.reset(); 282 m_identifier_table_ap.reset(); 283 m_selector_table_ap.reset(); 284 m_builtins_ap.reset(); 285} 286 287const char * 288ClangASTContext::GetTargetTriple () 289{ 290 return m_target_triple.c_str(); 291} 292 293void 294ClangASTContext::SetTargetTriple (const char *target_triple) 295{ 296 Clear(); 297 m_target_triple.assign(target_triple); 298} 299 300 301ASTContext * 302ClangASTContext::getASTContext() 303{ 304 if (m_ast_context_ap.get() == NULL) 305 { 306 m_ast_context_ap.reset( 307 new ASTContext( 308 *getLanguageOptions(), 309 *getSourceManager(), 310 *getTargetInfo(), 311 *getIdentifierTable(), 312 *getSelectorTable(), 313 *getBuiltinContext(), 314 0)); 315 } 316 return m_ast_context_ap.get(); 317} 318 319Builtin::Context * 320ClangASTContext::getBuiltinContext() 321{ 322 if (m_builtins_ap.get() == NULL) 323 m_builtins_ap.reset (new Builtin::Context(*getTargetInfo())); 324 return m_builtins_ap.get(); 325} 326 327IdentifierTable * 328ClangASTContext::getIdentifierTable() 329{ 330 if (m_identifier_table_ap.get() == NULL) 331 m_identifier_table_ap.reset(new IdentifierTable (*ClangASTContext::getLanguageOptions(), NULL)); 332 return m_identifier_table_ap.get(); 333} 334 335LangOptions * 336ClangASTContext::getLanguageOptions() 337{ 338 if (m_language_options_ap.get() == NULL) 339 { 340 m_language_options_ap.reset(new LangOptions()); 341 ParseLangArgs(*m_language_options_ap, IK_ObjCXX); 342// InitializeLangOptions(*m_language_options_ap, IK_ObjCXX); 343 } 344 return m_language_options_ap.get(); 345} 346 347SelectorTable * 348ClangASTContext::getSelectorTable() 349{ 350 if (m_selector_table_ap.get() == NULL) 351 m_selector_table_ap.reset (new SelectorTable()); 352 return m_selector_table_ap.get(); 353} 354 355clang::FileManager * 356ClangASTContext::getFileManager() 357{ 358 if (m_file_manager_ap.get() == NULL) 359 m_file_manager_ap.reset(new clang::FileManager()); 360 return m_file_manager_ap.get(); 361} 362 363clang::FileSystemOptions * 364ClangASTContext::getFileSystemOptions() 365{ 366 if (m_file_system_options_ap.get() == NULL) 367 m_file_system_options_ap.reset(new clang::FileSystemOptions()); 368 return m_file_system_options_ap.get(); 369} 370 371clang::SourceManager * 372ClangASTContext::getSourceManager() 373{ 374 if (m_source_manager_ap.get() == NULL) 375 m_source_manager_ap.reset(new clang::SourceManager(*getDiagnostic(), *getFileManager(), *getFileSystemOptions())); 376 return m_source_manager_ap.get(); 377} 378 379Diagnostic * 380ClangASTContext::getDiagnostic() 381{ 382 if (m_diagnostic_ap.get() == NULL) 383 { 384 llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_id_sp(new DiagnosticIDs()); 385 m_diagnostic_ap.reset(new Diagnostic(diag_id_sp)); 386 } 387 return m_diagnostic_ap.get(); 388} 389 390TargetOptions * 391ClangASTContext::getTargetOptions() 392{ 393 if (m_target_options_ap.get() == NULL && !m_target_triple.empty()) 394 { 395 m_target_options_ap.reset (new TargetOptions()); 396 if (m_target_options_ap.get()) 397 m_target_options_ap->Triple = m_target_triple; 398 } 399 return m_target_options_ap.get(); 400} 401 402 403TargetInfo * 404ClangASTContext::getTargetInfo() 405{ 406 // target_triple should be something like "x86_64-apple-darwin10" 407 if (m_target_info_ap.get() == NULL && !m_target_triple.empty()) 408 m_target_info_ap.reset (TargetInfo::CreateTargetInfo(*getDiagnostic(), *getTargetOptions())); 409 return m_target_info_ap.get(); 410} 411 412#pragma mark Basic Types 413 414static inline bool 415QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast_context, QualType qual_type) 416{ 417 uint64_t qual_type_bit_size = ast_context->getTypeSize(qual_type); 418 if (qual_type_bit_size == bit_size) 419 return true; 420 return false; 421} 422 423clang_type_t 424ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (Encoding encoding, uint32_t bit_size) 425{ 426 ASTContext *ast_context = getASTContext(); 427 428 assert (ast_context != NULL); 429 430 return GetBuiltinTypeForEncodingAndBitSize (ast_context, encoding, bit_size); 431} 432 433clang_type_t 434ClangASTContext::GetBuiltinTypeForEncodingAndBitSize (ASTContext *ast_context, Encoding encoding, uint32_t bit_size) 435{ 436 if (!ast_context) 437 return NULL; 438 439 switch (encoding) 440 { 441 case eEncodingInvalid: 442 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy)) 443 return ast_context->VoidPtrTy.getAsOpaquePtr(); 444 break; 445 446 case eEncodingUint: 447 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy)) 448 return ast_context->UnsignedCharTy.getAsOpaquePtr(); 449 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy)) 450 return ast_context->UnsignedShortTy.getAsOpaquePtr(); 451 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy)) 452 return ast_context->UnsignedIntTy.getAsOpaquePtr(); 453 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy)) 454 return ast_context->UnsignedLongTy.getAsOpaquePtr(); 455 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy)) 456 return ast_context->UnsignedLongLongTy.getAsOpaquePtr(); 457 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty)) 458 return ast_context->UnsignedInt128Ty.getAsOpaquePtr(); 459 break; 460 461 case eEncodingSint: 462 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy)) 463 return ast_context->CharTy.getAsOpaquePtr(); 464 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy)) 465 return ast_context->ShortTy.getAsOpaquePtr(); 466 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy)) 467 return ast_context->IntTy.getAsOpaquePtr(); 468 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy)) 469 return ast_context->LongTy.getAsOpaquePtr(); 470 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy)) 471 return ast_context->LongLongTy.getAsOpaquePtr(); 472 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty)) 473 return ast_context->Int128Ty.getAsOpaquePtr(); 474 break; 475 476 case eEncodingIEEE754: 477 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy)) 478 return ast_context->FloatTy.getAsOpaquePtr(); 479 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy)) 480 return ast_context->DoubleTy.getAsOpaquePtr(); 481 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy)) 482 return ast_context->LongDoubleTy.getAsOpaquePtr(); 483 break; 484 485 case eEncodingVector: 486 default: 487 break; 488 } 489 490 return NULL; 491} 492 493clang_type_t 494ClangASTContext::GetBuiltinTypeForDWARFEncodingAndBitSize (const char *type_name, uint32_t dw_ate, uint32_t bit_size) 495{ 496 ASTContext *ast_context = getASTContext(); 497 498 #define streq(a,b) strcmp(a,b) == 0 499 assert (ast_context != NULL); 500 if (ast_context) 501 { 502 switch (dw_ate) 503 { 504 default: 505 break; 506 507 case DW_ATE_address: 508 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->VoidPtrTy)) 509 return ast_context->VoidPtrTy.getAsOpaquePtr(); 510 break; 511 512 case DW_ATE_boolean: 513 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->BoolTy)) 514 return ast_context->BoolTy.getAsOpaquePtr(); 515 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy)) 516 return ast_context->UnsignedCharTy.getAsOpaquePtr(); 517 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy)) 518 return ast_context->UnsignedShortTy.getAsOpaquePtr(); 519 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy)) 520 return ast_context->UnsignedIntTy.getAsOpaquePtr(); 521 break; 522 523 case DW_ATE_complex_float: 524 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatComplexTy)) 525 return ast_context->FloatComplexTy.getAsOpaquePtr(); 526 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleComplexTy)) 527 return ast_context->DoubleComplexTy.getAsOpaquePtr(); 528 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleComplexTy)) 529 return ast_context->LongDoubleComplexTy.getAsOpaquePtr(); 530 break; 531 532 case DW_ATE_float: 533 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->FloatTy)) 534 return ast_context->FloatTy.getAsOpaquePtr(); 535 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->DoubleTy)) 536 return ast_context->DoubleTy.getAsOpaquePtr(); 537 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongDoubleTy)) 538 return ast_context->LongDoubleTy.getAsOpaquePtr(); 539 break; 540 541 case DW_ATE_signed: 542 if (type_name) 543 { 544 if (strstr(type_name, "long long")) 545 { 546 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy)) 547 return ast_context->LongLongTy.getAsOpaquePtr(); 548 } 549 else if (strstr(type_name, "long")) 550 { 551 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy)) 552 return ast_context->LongTy.getAsOpaquePtr(); 553 } 554 else if (strstr(type_name, "short")) 555 { 556 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy)) 557 return ast_context->ShortTy.getAsOpaquePtr(); 558 } 559 else if (strstr(type_name, "char")) 560 { 561 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy)) 562 return ast_context->CharTy.getAsOpaquePtr(); 563 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy)) 564 return ast_context->SignedCharTy.getAsOpaquePtr(); 565 } 566 else if (strstr(type_name, "int")) 567 { 568 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy)) 569 return ast_context->IntTy.getAsOpaquePtr(); 570 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty)) 571 return ast_context->Int128Ty.getAsOpaquePtr(); 572 } 573 else if (streq(type_name, "wchar_t")) 574 { 575 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->WCharTy)) 576 return ast_context->WCharTy.getAsOpaquePtr(); 577 } 578 } 579 // We weren't able to match up a type name, just search by size 580 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy)) 581 return ast_context->CharTy.getAsOpaquePtr(); 582 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->ShortTy)) 583 return ast_context->ShortTy.getAsOpaquePtr(); 584 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->IntTy)) 585 return ast_context->IntTy.getAsOpaquePtr(); 586 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongTy)) 587 return ast_context->LongTy.getAsOpaquePtr(); 588 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->LongLongTy)) 589 return ast_context->LongLongTy.getAsOpaquePtr(); 590 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->Int128Ty)) 591 return ast_context->Int128Ty.getAsOpaquePtr(); 592 break; 593 594 case DW_ATE_signed_char: 595 if (type_name) 596 { 597 if (streq(type_name, "signed char")) 598 { 599 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy)) 600 return ast_context->SignedCharTy.getAsOpaquePtr(); 601 } 602 } 603 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->CharTy)) 604 return ast_context->CharTy.getAsOpaquePtr(); 605 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->SignedCharTy)) 606 return ast_context->SignedCharTy.getAsOpaquePtr(); 607 break; 608 609 case DW_ATE_unsigned: 610 if (type_name) 611 { 612 if (strstr(type_name, "long long")) 613 { 614 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy)) 615 return ast_context->UnsignedLongLongTy.getAsOpaquePtr(); 616 } 617 else if (strstr(type_name, "long")) 618 { 619 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy)) 620 return ast_context->UnsignedLongTy.getAsOpaquePtr(); 621 } 622 else if (strstr(type_name, "short")) 623 { 624 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy)) 625 return ast_context->UnsignedShortTy.getAsOpaquePtr(); 626 } 627 else if (strstr(type_name, "char")) 628 { 629 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy)) 630 return ast_context->UnsignedCharTy.getAsOpaquePtr(); 631 } 632 else if (strstr(type_name, "int")) 633 { 634 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy)) 635 return ast_context->UnsignedIntTy.getAsOpaquePtr(); 636 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty)) 637 return ast_context->UnsignedInt128Ty.getAsOpaquePtr(); 638 } 639 } 640 // We weren't able to match up a type name, just search by size 641 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy)) 642 return ast_context->UnsignedCharTy.getAsOpaquePtr(); 643 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedShortTy)) 644 return ast_context->UnsignedShortTy.getAsOpaquePtr(); 645 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedIntTy)) 646 return ast_context->UnsignedIntTy.getAsOpaquePtr(); 647 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongTy)) 648 return ast_context->UnsignedLongTy.getAsOpaquePtr(); 649 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedLongLongTy)) 650 return ast_context->UnsignedLongLongTy.getAsOpaquePtr(); 651 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedInt128Ty)) 652 return ast_context->UnsignedInt128Ty.getAsOpaquePtr(); 653 break; 654 655 case DW_ATE_unsigned_char: 656 if (QualTypeMatchesBitSize (bit_size, ast_context, ast_context->UnsignedCharTy)) 657 return ast_context->UnsignedCharTy.getAsOpaquePtr(); 658 break; 659 660 case DW_ATE_imaginary_float: 661 break; 662 } 663 } 664 // This assert should fire for anything that we don't catch above so we know 665 // to fix any issues we run into. 666 assert (!"error: ClangASTContext::GetClangTypeForDWARFEncodingAndSize() contains an unhandled encoding. Fix this ASAP!"); 667 return NULL; 668} 669 670clang_type_t 671ClangASTContext::GetBuiltInType_void(ASTContext *ast_context) 672{ 673 return ast_context->VoidTy.getAsOpaquePtr(); 674} 675 676clang_type_t 677ClangASTContext::GetBuiltInType_bool() 678{ 679 return getASTContext()->BoolTy.getAsOpaquePtr(); 680} 681 682clang_type_t 683ClangASTContext::GetBuiltInType_objc_id() 684{ 685 return getASTContext()->ObjCBuiltinIdTy.getAsOpaquePtr(); 686} 687 688clang_type_t 689ClangASTContext::GetBuiltInType_objc_Class() 690{ 691 return getASTContext()->ObjCBuiltinClassTy.getAsOpaquePtr(); 692} 693 694clang_type_t 695ClangASTContext::GetBuiltInType_objc_selector() 696{ 697 return getASTContext()->ObjCBuiltinSelTy.getAsOpaquePtr(); 698} 699 700clang_type_t 701ClangASTContext::GetCStringType (bool is_const) 702{ 703 QualType char_type(getASTContext()->CharTy); 704 705 if (is_const) 706 char_type.addConst(); 707 708 return getASTContext()->getPointerType(char_type).getAsOpaquePtr(); 709} 710 711clang_type_t 712ClangASTContext::GetVoidPtrType (bool is_const) 713{ 714 return GetVoidPtrType(getASTContext(), is_const); 715} 716 717clang_type_t 718ClangASTContext::GetVoidPtrType (ASTContext *ast_context, bool is_const) 719{ 720 QualType void_ptr_type(ast_context->VoidPtrTy); 721 722 if (is_const) 723 void_ptr_type.addConst(); 724 725 return void_ptr_type.getAsOpaquePtr(); 726} 727 728class NullDiagnosticClient : public DiagnosticClient 729{ 730public: 731 NullDiagnosticClient () 732 { 733 m_log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); 734 } 735 736 void HandleDiagnostic (Diagnostic::Level DiagLevel, const DiagnosticInfo &info) 737 { 738 if (m_log) 739 { 740 llvm::SmallVectorImpl<char> diag_str(10); 741 info.FormatDiagnostic(diag_str); 742 diag_str.push_back('\0'); 743 m_log->Printf("Compiler diagnostic: %s\n", diag_str.data()); 744 } 745 } 746private: 747 LogSP m_log; 748}; 749 750clang_type_t 751ClangASTContext::CopyType (ASTContext *dest_context, 752 ASTContext *source_context, 753 clang_type_t clang_type) 754{ 755 // null_client's ownership is transferred to diagnostics 756 FileManager file_manager; 757 FileSystemOptions file_system_options; 758 ASTImporter importer(*dest_context, file_manager, file_system_options, 759 *source_context, file_manager, file_system_options); 760 761 QualType src = QualType::getFromOpaquePtr(clang_type); 762 QualType dst = importer.Import(src); 763 764 return dst.getAsOpaquePtr(); 765} 766 767 768clang::Decl * 769ClangASTContext::CopyDecl (ASTContext *dest_context, 770 ASTContext *source_context, 771 clang::Decl *source_decl) 772{ 773 // null_client's ownership is transferred to diagnostics 774 FileManager file_manager; 775 FileSystemOptions file_system_options; 776 ASTImporter importer(*dest_context, file_manager, file_system_options, 777 *source_context, file_manager, file_system_options); 778 779 return importer.Import(source_decl); 780} 781 782bool 783ClangASTContext::AreTypesSame(ASTContext *ast_context, 784 clang_type_t type1, 785 clang_type_t type2) 786{ 787 return ast_context->hasSameType(QualType::getFromOpaquePtr(type1), 788 QualType::getFromOpaquePtr(type2)); 789} 790 791#pragma mark CVR modifiers 792 793clang_type_t 794ClangASTContext::AddConstModifier (clang_type_t clang_type) 795{ 796 if (clang_type) 797 { 798 QualType result(QualType::getFromOpaquePtr(clang_type)); 799 result.addConst(); 800 return result.getAsOpaquePtr(); 801 } 802 return NULL; 803} 804 805clang_type_t 806ClangASTContext::AddRestrictModifier (clang_type_t clang_type) 807{ 808 if (clang_type) 809 { 810 QualType result(QualType::getFromOpaquePtr(clang_type)); 811 result.getQualifiers().setRestrict (true); 812 return result.getAsOpaquePtr(); 813 } 814 return NULL; 815} 816 817clang_type_t 818ClangASTContext::AddVolatileModifier (clang_type_t clang_type) 819{ 820 if (clang_type) 821 { 822 QualType result(QualType::getFromOpaquePtr(clang_type)); 823 result.getQualifiers().setVolatile (true); 824 return result.getAsOpaquePtr(); 825 } 826 return NULL; 827} 828 829#pragma mark Structure, Unions, Classes 830 831clang_type_t 832ClangASTContext::CreateRecordType (const char *name, int kind, DeclContext *decl_ctx, LanguageType language) 833{ 834 ASTContext *ast_context = getASTContext(); 835 assert (ast_context != NULL); 836 837 if (decl_ctx == NULL) 838 decl_ctx = ast_context->getTranslationUnitDecl(); 839 840 841 if (language == eLanguageTypeObjC) 842 { 843 bool isForwardDecl = true; 844 bool isInternal = false; 845 return CreateObjCClass (name, decl_ctx, isForwardDecl, isInternal); 846 } 847 848 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and 849 // we will need to update this code. I was told to currently always use 850 // the CXXRecordDecl class since we often don't know from debug information 851 // if something is struct or a class, so we default to always use the more 852 // complete definition just in case. 853 CXXRecordDecl *decl = CXXRecordDecl::Create(*ast_context, 854 (TagDecl::TagKind)kind, 855 decl_ctx, 856 SourceLocation(), 857 name && name[0] ? &ast_context->Idents.get(name) : NULL); 858 859 return ast_context->getTagDeclType(decl).getAsOpaquePtr(); 860} 861 862static bool 863IsOperator (const char *name, OverloadedOperatorKind &op_kind) 864{ 865 if (name == NULL || name[0] == '\0') 866 return false; 867 868 if (::strstr(name, "operator ") != name) 869 return false; 870 871 const char *post_op_name = name + 9; 872 873 // This is an operator, set the overloaded operator kind to invalid 874 // in case this is a conversion operator... 875 op_kind = NUM_OVERLOADED_OPERATORS; 876 877 switch (post_op_name[0]) 878 { 879 case 'n': 880 if (strcmp (post_op_name, "new") == 0) 881 op_kind = OO_New; 882 else if (strcmp (post_op_name, "new[]") == 0) 883 op_kind = OO_Array_New; 884 break; 885 886 case 'd': 887 if (strcmp (post_op_name, "delete") == 0) 888 op_kind = OO_Delete; 889 else if (strcmp (post_op_name, "delete[]") == 0) 890 op_kind = OO_Array_Delete; 891 break; 892 893 case '+': 894 if (post_op_name[1] == '\0') 895 op_kind = OO_Plus; 896 else if (post_op_name[2] == '\0') 897 { 898 if (post_op_name[1] == '=') 899 op_kind = OO_PlusEqual; 900 else if (post_op_name[1] == '+') 901 op_kind = OO_PlusPlus; 902 } 903 break; 904 905 case '-': 906 if (post_op_name[1] == '\0') 907 op_kind = OO_Minus; 908 else if (post_op_name[2] == '\0') 909 { 910 switch (post_op_name[1]) 911 { 912 case '=': op_kind = OO_MinusEqual; break; 913 case '-': op_kind = OO_MinusMinus; break; 914 case '>': op_kind = OO_Arrow; break; 915 } 916 } 917 else if (post_op_name[3] == '\0') 918 { 919 if (post_op_name[2] == '*') 920 op_kind = OO_ArrowStar; break; 921 } 922 break; 923 924 case '*': 925 if (post_op_name[1] == '\0') 926 op_kind = OO_Star; 927 else if (post_op_name[1] == '=' && post_op_name[2] == '\0') 928 op_kind = OO_StarEqual; 929 break; 930 931 case '/': 932 if (post_op_name[1] == '\0') 933 op_kind = OO_Slash; 934 else if (post_op_name[1] == '=' && post_op_name[2] == '\0') 935 op_kind = OO_SlashEqual; 936 break; 937 938 case '%': 939 if (post_op_name[1] == '\0') 940 op_kind = OO_Percent; 941 else if (post_op_name[1] == '=' && post_op_name[2] == '\0') 942 op_kind = OO_PercentEqual; 943 break; 944 945 946 case '^': 947 if (post_op_name[1] == '\0') 948 op_kind = OO_Caret; 949 else if (post_op_name[1] == '=' && post_op_name[2] == '\0') 950 op_kind = OO_CaretEqual; 951 break; 952 953 case '&': 954 if (post_op_name[1] == '\0') 955 op_kind = OO_Amp; 956 else if (post_op_name[2] == '\0') 957 { 958 switch (post_op_name[1]) 959 { 960 case '=': op_kind = OO_AmpEqual; break; 961 case '&': op_kind = OO_AmpAmp; break; 962 } 963 } 964 break; 965 966 case '|': 967 if (post_op_name[1] == '\0') 968 op_kind = OO_Pipe; 969 else if (post_op_name[2] == '\0') 970 { 971 switch (post_op_name[1]) 972 { 973 case '=': op_kind = OO_PipeEqual; break; 974 case '|': op_kind = OO_PipePipe; break; 975 } 976 } 977 break; 978 979 case '~': 980 if (post_op_name[1] == '\0') 981 op_kind = OO_Tilde; 982 break; 983 984 case '!': 985 if (post_op_name[1] == '\0') 986 op_kind = OO_Exclaim; 987 else if (post_op_name[1] == '=' && post_op_name[2] == '\0') 988 op_kind = OO_ExclaimEqual; 989 break; 990 991 case '=': 992 if (post_op_name[1] == '\0') 993 op_kind = OO_Equal; 994 else if (post_op_name[1] == '=' && post_op_name[2] == '\0') 995 op_kind = OO_EqualEqual; 996 break; 997 998 case '<': 999 if (post_op_name[1] == '\0') 1000 op_kind = OO_Less; 1001 else if (post_op_name[2] == '\0') 1002 { 1003 switch (post_op_name[1]) 1004 { 1005 case '<': op_kind = OO_LessLess; break; 1006 case '=': op_kind = OO_LessEqual; break; 1007 } 1008 } 1009 else if (post_op_name[3] == '\0') 1010 { 1011 if (post_op_name[2] == '=') 1012 op_kind = OO_LessLessEqual; 1013 } 1014 break; 1015 1016 case '>': 1017 if (post_op_name[1] == '\0') 1018 op_kind = OO_Greater; 1019 else if (post_op_name[2] == '\0') 1020 { 1021 switch (post_op_name[1]) 1022 { 1023 case '>': op_kind = OO_GreaterGreater; break; 1024 case '=': op_kind = OO_GreaterEqual; break; 1025 } 1026 } 1027 else if (post_op_name[1] == '>' && 1028 post_op_name[2] == '=' && 1029 post_op_name[3] == '\0') 1030 { 1031 op_kind = OO_GreaterGreaterEqual; 1032 } 1033 break; 1034 1035 case ',': 1036 if (post_op_name[1] == '\0') 1037 op_kind = OO_Comma; 1038 break; 1039 1040 case '(': 1041 if (post_op_name[1] == ')' && post_op_name[2] == '\0') 1042 op_kind = OO_Call; 1043 break; 1044 1045 case '[': 1046 if (post_op_name[1] == ']' && post_op_name[2] == '\0') 1047 op_kind = OO_Subscript; 1048 break; 1049 } 1050 1051 return true; 1052} 1053CXXMethodDecl * 1054ClangASTContext::AddMethodToCXXRecordType 1055( 1056 ASTContext *ast_context, 1057 clang_type_t record_opaque_type, 1058 const char *name, 1059 clang_type_t method_opaque_type, 1060 lldb::AccessType access, 1061 bool is_virtual, 1062 bool is_static, 1063 bool is_inline, 1064 bool is_explicit 1065) 1066{ 1067 if (!record_opaque_type || !method_opaque_type || !name) 1068 return NULL; 1069 1070 assert(ast_context); 1071 1072 IdentifierTable *identifier_table = &ast_context->Idents; 1073 1074 assert(identifier_table); 1075 1076 QualType record_qual_type(QualType::getFromOpaquePtr(record_opaque_type)); 1077 1078 clang::Type *clang_type(record_qual_type.getTypePtr()); 1079 1080 if (clang_type == NULL) 1081 return NULL; 1082 1083 RecordType *record_clang_type(dyn_cast<RecordType>(clang_type)); 1084 1085 if (record_clang_type == NULL) 1086 return NULL; 1087 1088 RecordDecl *record_decl = record_clang_type->getDecl(); 1089 1090 if (record_decl == NULL) 1091 return NULL; 1092 1093 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 1094 1095 if (cxx_record_decl == NULL) 1096 return NULL; 1097 1098 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type)); 1099 1100 method_qual_type.dump(); 1101 1102 CXXMethodDecl *cxx_method_decl = NULL; 1103 1104 DeclarationName decl_name (&identifier_table->get(name)); 1105 1106 const bool is_implicitly_declared = false; 1107 1108 clang::FunctionType *function_Type = dyn_cast<FunctionType>(method_qual_type.getTypePtr()); 1109 1110 if (function_Type == NULL) 1111 return NULL; 1112 1113 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(function_Type)); 1114 1115 if (!method_function_prototype) 1116 return NULL; 1117 1118 unsigned int num_params = method_function_prototype->getNumArgs(); 1119 1120 if (name[0] == '~') 1121 { 1122 cxx_method_decl = CXXDestructorDecl::Create (*ast_context, 1123 cxx_record_decl, 1124 DeclarationNameInfo (ast_context->DeclarationNames.getCXXDestructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()), 1125 method_qual_type, 1126 NULL, 1127 is_inline, 1128 is_implicitly_declared); 1129 } 1130 else if (decl_name == record_decl->getDeclName()) 1131 { 1132 cxx_method_decl = CXXConstructorDecl::Create (*ast_context, 1133 cxx_record_decl, 1134 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConstructorName (ast_context->getCanonicalType (record_qual_type)), SourceLocation()), 1135 method_qual_type, 1136 NULL, // TypeSourceInfo * 1137 is_explicit, 1138 is_inline, 1139 is_implicitly_declared); 1140 } 1141 else 1142 { 1143 1144 OverloadedOperatorKind op_kind = NUM_OVERLOADED_OPERATORS; 1145 if (IsOperator (name, op_kind)) 1146 { 1147 if (op_kind != NUM_OVERLOADED_OPERATORS) 1148 { 1149 cxx_method_decl = CXXMethodDecl::Create (*ast_context, 1150 cxx_record_decl, 1151 DeclarationNameInfo (ast_context->DeclarationNames.getCXXOperatorName (op_kind), SourceLocation()), 1152 method_qual_type, 1153 NULL, // TypeSourceInfo * 1154 is_static, 1155 SC_None, 1156 is_inline); 1157 } 1158 else if (num_params == 0) 1159 { 1160 // Conversion operators don't take params... 1161 cxx_method_decl = CXXConversionDecl::Create (*ast_context, 1162 cxx_record_decl, 1163 DeclarationNameInfo (ast_context->DeclarationNames.getCXXConversionFunctionName (ast_context->getCanonicalType (function_Type->getResultType())), SourceLocation()), 1164 method_qual_type, 1165 NULL, // TypeSourceInfo * 1166 is_inline, 1167 is_explicit); 1168 } 1169 } 1170 1171 if (cxx_method_decl == NULL) 1172 { 1173 cxx_method_decl = CXXMethodDecl::Create (*ast_context, 1174 cxx_record_decl, 1175 DeclarationNameInfo (decl_name, SourceLocation()), 1176 method_qual_type, 1177 NULL, // TypeSourceInfo * 1178 is_static, 1179 SC_None, 1180 is_inline); 1181 } 1182 } 1183 1184 AccessSpecifier access_specifier = ConvertAccessTypeToAccessSpecifier (access); 1185 1186 cxx_method_decl->setAccess (access_specifier); 1187 cxx_method_decl->setVirtualAsWritten (is_virtual); 1188 1189 // Populate the method decl with parameter decls 1190 1191 ParmVarDecl *params[num_params]; 1192 1193 for (int param_index = 0; 1194 param_index < num_params; 1195 ++param_index) 1196 { 1197 params[param_index] = ParmVarDecl::Create (*ast_context, 1198 cxx_method_decl, 1199 SourceLocation(), 1200 NULL, // anonymous 1201 method_function_prototype->getArgType(param_index), 1202 NULL, 1203 SC_None, 1204 SC_None, 1205 NULL); 1206 } 1207 1208 cxx_method_decl->setParams (params, num_params); 1209 1210 cxx_record_decl->addDecl (cxx_method_decl); 1211 1212 return cxx_method_decl; 1213} 1214 1215bool 1216ClangASTContext::AddFieldToRecordType 1217( 1218 ASTContext *ast_context, 1219 clang_type_t record_clang_type, 1220 const char *name, 1221 clang_type_t field_type, 1222 AccessType access, 1223 uint32_t bitfield_bit_size 1224) 1225{ 1226 if (record_clang_type == NULL || field_type == NULL) 1227 return false; 1228 1229 IdentifierTable *identifier_table = &ast_context->Idents; 1230 1231 assert (ast_context != NULL); 1232 assert (identifier_table != NULL); 1233 1234 QualType record_qual_type(QualType::getFromOpaquePtr(record_clang_type)); 1235 1236 clang::Type *clang_type = record_qual_type.getTypePtr(); 1237 if (clang_type) 1238 { 1239 const RecordType *record_type = dyn_cast<RecordType>(clang_type); 1240 1241 if (record_type) 1242 { 1243 RecordDecl *record_decl = record_type->getDecl(); 1244 1245 clang::Expr *bit_width = NULL; 1246 if (bitfield_bit_size != 0) 1247 { 1248 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size); 1249 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation()); 1250 } 1251 FieldDecl *field = FieldDecl::Create (*ast_context, 1252 record_decl, 1253 SourceLocation(), 1254 name ? &identifier_table->get(name) : NULL, // Identifier 1255 QualType::getFromOpaquePtr(field_type), // Field type 1256 NULL, // DeclaratorInfo * 1257 bit_width, // BitWidth 1258 false); // Mutable 1259 1260 field->setAccess (ConvertAccessTypeToAccessSpecifier (access)); 1261 1262 if (field) 1263 { 1264 record_decl->addDecl(field); 1265 } 1266 } 1267 else 1268 { 1269 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(clang_type); 1270 if (objc_class_type) 1271 { 1272 bool is_synthesized = false; 1273 ClangASTContext::AddObjCClassIVar (ast_context, 1274 record_clang_type, 1275 name, 1276 field_type, 1277 access, 1278 bitfield_bit_size, 1279 is_synthesized); 1280 } 1281 } 1282 } 1283 return false; 1284} 1285 1286bool 1287ClangASTContext::FieldIsBitfield (FieldDecl* field, uint32_t& bitfield_bit_size) 1288{ 1289 return FieldIsBitfield(getASTContext(), field, bitfield_bit_size); 1290} 1291 1292bool 1293ClangASTContext::FieldIsBitfield 1294( 1295 ASTContext *ast_context, 1296 FieldDecl* field, 1297 uint32_t& bitfield_bit_size 1298) 1299{ 1300 if (ast_context == NULL || field == NULL) 1301 return false; 1302 1303 if (field->isBitField()) 1304 { 1305 Expr* bit_width_expr = field->getBitWidth(); 1306 if (bit_width_expr) 1307 { 1308 llvm::APSInt bit_width_apsint; 1309 if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, *ast_context)) 1310 { 1311 bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX); 1312 return true; 1313 } 1314 } 1315 } 1316 return false; 1317} 1318 1319bool 1320ClangASTContext::RecordHasFields (const RecordDecl *record_decl) 1321{ 1322 if (record_decl == NULL) 1323 return false; 1324 1325 if (!record_decl->field_empty()) 1326 return true; 1327 1328 // No fields, lets check this is a CXX record and check the base classes 1329 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 1330 if (cxx_record_decl) 1331 { 1332 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 1333 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 1334 base_class != base_class_end; 1335 ++base_class) 1336 { 1337 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 1338 if (RecordHasFields(base_class_decl)) 1339 return true; 1340 } 1341 } 1342 return false; 1343} 1344 1345void 1346ClangASTContext::SetDefaultAccessForRecordFields (clang_type_t clang_qual_type, int default_accessibility, int *assigned_accessibilities, size_t num_assigned_accessibilities) 1347{ 1348 if (clang_qual_type) 1349 { 1350 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type)); 1351 clang::Type *clang_type = qual_type.getTypePtr(); 1352 if (clang_type) 1353 { 1354 RecordType *record_type = dyn_cast<RecordType>(clang_type); 1355 if (record_type) 1356 { 1357 RecordDecl *record_decl = record_type->getDecl(); 1358 if (record_decl) 1359 { 1360 uint32_t field_idx; 1361 RecordDecl::field_iterator field, field_end; 1362 for (field = record_decl->field_begin(), field_end = record_decl->field_end(), field_idx = 0; 1363 field != field_end; 1364 ++field, ++field_idx) 1365 { 1366 // If no accessibility was assigned, assign the correct one 1367 if (field_idx < num_assigned_accessibilities && assigned_accessibilities[field_idx] == clang::AS_none) 1368 field->setAccess ((AccessSpecifier)default_accessibility); 1369 } 1370 } 1371 } 1372 } 1373 } 1374} 1375 1376#pragma mark C++ Base Classes 1377 1378CXXBaseSpecifier * 1379ClangASTContext::CreateBaseClassSpecifier (clang_type_t base_class_type, AccessType access, bool is_virtual, bool base_of_class) 1380{ 1381 if (base_class_type) 1382 return new CXXBaseSpecifier (SourceRange(), 1383 is_virtual, 1384 base_of_class, 1385 ConvertAccessTypeToAccessSpecifier (access), 1386 getASTContext()->CreateTypeSourceInfo (QualType::getFromOpaquePtr(base_class_type))); 1387 return NULL; 1388} 1389 1390void 1391ClangASTContext::DeleteBaseClassSpecifiers (CXXBaseSpecifier **base_classes, unsigned num_base_classes) 1392{ 1393 for (unsigned i=0; i<num_base_classes; ++i) 1394 { 1395 delete base_classes[i]; 1396 base_classes[i] = NULL; 1397 } 1398} 1399 1400bool 1401ClangASTContext::SetBaseClassesForClassType (clang_type_t class_clang_type, CXXBaseSpecifier const * const *base_classes, unsigned num_base_classes) 1402{ 1403 if (class_clang_type) 1404 { 1405 clang::Type *clang_type = QualType::getFromOpaquePtr(class_clang_type).getTypePtr(); 1406 if (clang_type) 1407 { 1408 RecordType *record_type = dyn_cast<RecordType>(clang_type); 1409 if (record_type) 1410 { 1411 CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_type->getDecl()); 1412 if (cxx_record_decl) 1413 { 1414 cxx_record_decl->setBases(base_classes, num_base_classes); 1415 return true; 1416 } 1417 } 1418 } 1419 } 1420 return false; 1421} 1422#pragma mark Objective C Classes 1423 1424clang_type_t 1425ClangASTContext::CreateObjCClass 1426( 1427 const char *name, 1428 DeclContext *decl_ctx, 1429 bool isForwardDecl, 1430 bool isInternal 1431) 1432{ 1433 ASTContext *ast_context = getASTContext(); 1434 assert (ast_context != NULL); 1435 assert (name && name[0]); 1436 if (decl_ctx == NULL) 1437 decl_ctx = ast_context->getTranslationUnitDecl(); 1438 1439 // NOTE: Eventually CXXRecordDecl will be merged back into RecordDecl and 1440 // we will need to update this code. I was told to currently always use 1441 // the CXXRecordDecl class since we often don't know from debug information 1442 // if something is struct or a class, so we default to always use the more 1443 // complete definition just in case. 1444 ObjCInterfaceDecl *decl = ObjCInterfaceDecl::Create (*ast_context, 1445 decl_ctx, 1446 SourceLocation(), 1447 &ast_context->Idents.get(name), 1448 SourceLocation(), 1449 isForwardDecl, 1450 isInternal); 1451 1452 return ast_context->getObjCInterfaceType(decl).getAsOpaquePtr(); 1453} 1454 1455bool 1456ClangASTContext::SetObjCSuperClass (clang_type_t class_opaque_type, clang_type_t super_opaque_type) 1457{ 1458 if (class_opaque_type && super_opaque_type) 1459 { 1460 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); 1461 QualType super_qual_type(QualType::getFromOpaquePtr(super_opaque_type)); 1462 clang::Type *class_type = class_qual_type.getTypePtr(); 1463 clang::Type *super_type = super_qual_type.getTypePtr(); 1464 if (class_type && super_type) 1465 { 1466 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); 1467 ObjCObjectType *objc_super_type = dyn_cast<ObjCObjectType>(super_type); 1468 if (objc_class_type && objc_super_type) 1469 { 1470 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 1471 ObjCInterfaceDecl *super_interface_decl = objc_super_type->getInterface(); 1472 if (class_interface_decl && super_interface_decl) 1473 { 1474 class_interface_decl->setSuperClass(super_interface_decl); 1475 return true; 1476 } 1477 } 1478 } 1479 } 1480 return false; 1481} 1482 1483 1484bool 1485ClangASTContext::AddObjCClassIVar 1486( 1487 ASTContext *ast_context, 1488 clang_type_t class_opaque_type, 1489 const char *name, 1490 clang_type_t ivar_opaque_type, 1491 AccessType access, 1492 uint32_t bitfield_bit_size, 1493 bool is_synthesized 1494) 1495{ 1496 if (class_opaque_type == NULL || ivar_opaque_type == NULL) 1497 return false; 1498 1499 IdentifierTable *identifier_table = &ast_context->Idents; 1500 1501 assert (ast_context != NULL); 1502 assert (identifier_table != NULL); 1503 1504 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); 1505 1506 clang::Type *class_type = class_qual_type.getTypePtr(); 1507 if (class_type) 1508 { 1509 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); 1510 1511 if (objc_class_type) 1512 { 1513 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 1514 1515 if (class_interface_decl) 1516 { 1517 clang::Expr *bit_width = NULL; 1518 if (bitfield_bit_size != 0) 1519 { 1520 APInt bitfield_bit_size_apint(ast_context->getTypeSize(ast_context->IntTy), bitfield_bit_size); 1521 bit_width = new (*ast_context)IntegerLiteral (*ast_context, bitfield_bit_size_apint, ast_context->IntTy, SourceLocation()); 1522 } 1523 1524 ObjCIvarDecl *field = ObjCIvarDecl::Create (*ast_context, 1525 class_interface_decl, 1526 SourceLocation(), 1527 &identifier_table->get(name), // Identifier 1528 QualType::getFromOpaquePtr(ivar_opaque_type), // Field type 1529 NULL, // TypeSourceInfo * 1530 ConvertAccessTypeToObjCIvarAccessControl (access), 1531 bit_width, 1532 is_synthesized); 1533 1534 if (field) 1535 { 1536 class_interface_decl->addDecl(field); 1537 return true; 1538 } 1539 } 1540 } 1541 } 1542 return false; 1543} 1544 1545 1546bool 1547ClangASTContext::ObjCTypeHasIVars (clang_type_t class_opaque_type, bool check_superclass) 1548{ 1549 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); 1550 1551 clang::Type *class_type = class_qual_type.getTypePtr(); 1552 if (class_type) 1553 { 1554 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); 1555 1556 if (objc_class_type) 1557 return ObjCDeclHasIVars (objc_class_type->getInterface(), check_superclass); 1558 } 1559 return false; 1560} 1561 1562bool 1563ClangASTContext::ObjCDeclHasIVars (ObjCInterfaceDecl *class_interface_decl, bool check_superclass) 1564{ 1565 while (class_interface_decl) 1566 { 1567 if (class_interface_decl->ivar_size() > 0) 1568 return true; 1569 1570 if (check_superclass) 1571 class_interface_decl = class_interface_decl->getSuperClass(); 1572 else 1573 break; 1574 } 1575 return false; 1576} 1577 1578ObjCMethodDecl * 1579ClangASTContext::AddMethodToObjCObjectType 1580( 1581 ASTContext *ast_context, 1582 clang_type_t class_opaque_type, 1583 const char *name, // the full symbol name as seen in the symbol table ("-[NString stringWithCString:]") 1584 clang_type_t method_opaque_type, 1585 lldb::AccessType access 1586) 1587{ 1588 if (class_opaque_type == NULL || method_opaque_type == NULL) 1589 return NULL; 1590 1591 IdentifierTable *identifier_table = &ast_context->Idents; 1592 1593 assert (ast_context != NULL); 1594 assert (identifier_table != NULL); 1595 1596 QualType class_qual_type(QualType::getFromOpaquePtr(class_opaque_type)); 1597 1598 clang::Type *class_type = class_qual_type.getTypePtr(); 1599 if (class_type == NULL) 1600 return NULL; 1601 1602 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(class_type); 1603 1604 if (objc_class_type == NULL) 1605 return NULL; 1606 1607 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 1608 1609 if (class_interface_decl == NULL) 1610 return NULL; 1611 1612 const char *selector_start = ::strchr (name, ' '); 1613 if (selector_start == NULL) 1614 return NULL; 1615 1616 selector_start++; 1617 if (!(::isalpha (selector_start[0]) || selector_start[0] == '_')) 1618 return NULL; 1619 llvm::SmallVector<IdentifierInfo *, 12> selector_idents; 1620 1621 size_t len = 0; 1622 const char *start; 1623 //printf ("name = '%s'\n", name); 1624 1625 unsigned num_selectors_with_args = 0; 1626 for (start = selector_start; 1627 start && *start != '\0' && *start != ']'; 1628 start += len) 1629 { 1630 len = ::strcspn(start, ":]"); 1631 bool has_arg = (start[len] == ':'); 1632 if (has_arg) 1633 ++num_selectors_with_args; 1634 selector_idents.push_back (&identifier_table->get (StringRef (start, len))); 1635 if (has_arg) 1636 len += 1; 1637 } 1638 1639 1640 if (selector_idents.size() == 0) 1641 return 0; 1642 1643 clang::Selector method_selector = ast_context->Selectors.getSelector (num_selectors_with_args ? selector_idents.size() : 0, 1644 selector_idents.data()); 1645 1646 QualType method_qual_type (QualType::getFromOpaquePtr (method_opaque_type)); 1647 1648 // Populate the method decl with parameter decls 1649 clang::Type *method_type(method_qual_type.getTypePtr()); 1650 1651 if (method_type == NULL) 1652 return NULL; 1653 1654 FunctionProtoType *method_function_prototype (dyn_cast<FunctionProtoType>(method_type)); 1655 1656 if (!method_function_prototype) 1657 return NULL; 1658 1659 1660 bool is_variadic = false; 1661 bool is_synthesized = false; 1662 bool is_defined = false; 1663 ObjCMethodDecl::ImplementationControl imp_control = ObjCMethodDecl::None; 1664 1665 const unsigned num_args = method_function_prototype->getNumArgs(); 1666 1667 ObjCMethodDecl *objc_method_decl = ObjCMethodDecl::Create (*ast_context, 1668 SourceLocation(), // beginLoc, 1669 SourceLocation(), // endLoc, 1670 method_selector, 1671 method_function_prototype->getResultType(), 1672 NULL, // TypeSourceInfo *ResultTInfo, 1673 GetDeclContextForType (class_opaque_type), 1674 name[0] == '-', 1675 is_variadic, 1676 is_synthesized, 1677 is_defined, 1678 imp_control, 1679 num_args); 1680 1681 1682 if (objc_method_decl == NULL) 1683 return NULL; 1684 1685 if (num_args > 0) 1686 { 1687 llvm::SmallVector<ParmVarDecl *, 12> params; 1688 1689 for (int param_index = 0; param_index < num_args; ++param_index) 1690 { 1691 params.push_back (ParmVarDecl::Create (*ast_context, 1692 objc_method_decl, 1693 SourceLocation(), 1694 NULL, // anonymous 1695 method_function_prototype->getArgType(param_index), 1696 NULL, 1697 SC_Auto, 1698 SC_Auto, 1699 NULL)); 1700 } 1701 1702 objc_method_decl->setMethodParams(*ast_context, params.data(), params.size(), num_args); 1703 } 1704 1705 class_interface_decl->addDecl (objc_method_decl); 1706 1707 1708 return objc_method_decl; 1709} 1710 1711 1712uint32_t 1713ClangASTContext::GetTypeInfo 1714( 1715 clang_type_t clang_type, 1716 clang::ASTContext *ast_context, 1717 clang_type_t *pointee_or_element_clang_type 1718) 1719{ 1720 if (clang_type == NULL) 1721 return 0; 1722 1723 if (pointee_or_element_clang_type) 1724 *pointee_or_element_clang_type = NULL; 1725 1726 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 1727 1728 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 1729 switch (type_class) 1730 { 1731 case clang::Type::Builtin: 1732 switch (cast<clang::BuiltinType>(qual_type)->getKind()) 1733 { 1734 case clang::BuiltinType::ObjCId: 1735 case clang::BuiltinType::ObjCClass: 1736 if (ast_context && pointee_or_element_clang_type) 1737 *pointee_or_element_clang_type = ast_context->ObjCBuiltinClassTy.getAsOpaquePtr(); 1738 return eTypeIsBuiltIn | eTypeIsPointer | eTypeHasValue; 1739 1740 default: 1741 break; 1742 } 1743 return eTypeIsBuiltIn | eTypeHasValue; 1744 1745 case clang::Type::BlockPointer: 1746 if (pointee_or_element_clang_type) 1747 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr(); 1748 return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock; 1749 1750 case clang::Type::Complex: return eTypeHasChildren | eTypeIsBuiltIn | eTypeHasValue; 1751 1752 case clang::Type::ConstantArray: 1753 case clang::Type::DependentSizedArray: 1754 case clang::Type::IncompleteArray: 1755 case clang::Type::VariableArray: 1756 if (pointee_or_element_clang_type) 1757 *pointee_or_element_clang_type = cast<ArrayType>(qual_type.getTypePtr())->getElementType().getAsOpaquePtr(); 1758 return eTypeHasChildren | eTypeIsArray; 1759 1760 case clang::Type::DependentName: return 0; 1761 case clang::Type::DependentSizedExtVector: return eTypeHasChildren | eTypeIsVector; 1762 case clang::Type::DependentTemplateSpecialization: return eTypeIsTemplate; 1763 case clang::Type::Decltype: return 0; 1764 1765 case clang::Type::Enum: 1766 if (pointee_or_element_clang_type) 1767 *pointee_or_element_clang_type = cast<EnumType>(qual_type)->getDecl()->getIntegerType().getAsOpaquePtr(); 1768 return eTypeIsEnumeration | eTypeHasValue; 1769 1770 case clang::Type::Elaborated: return 0; 1771 case clang::Type::ExtVector: return eTypeHasChildren | eTypeIsVector; 1772 case clang::Type::FunctionProto: return eTypeIsFuncPrototype | eTypeHasValue; 1773 case clang::Type::FunctionNoProto: return eTypeIsFuncPrototype | eTypeHasValue; 1774 case clang::Type::InjectedClassName: return 0; 1775 1776 case clang::Type::LValueReference: 1777 case clang::Type::RValueReference: 1778 if (pointee_or_element_clang_type) 1779 *pointee_or_element_clang_type = cast<ReferenceType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(); 1780 return eTypeHasChildren | eTypeIsReference | eTypeHasValue; 1781 1782 case clang::Type::MemberPointer: return eTypeIsPointer | eTypeIsMember | eTypeHasValue; 1783 1784 case clang::Type::ObjCObjectPointer: 1785 if (pointee_or_element_clang_type) 1786 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr(); 1787 return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer | eTypeHasValue; 1788 1789 case clang::Type::ObjCObject: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass; 1790 case clang::Type::ObjCInterface: return eTypeHasChildren | eTypeIsObjC | eTypeIsClass; 1791 1792 case clang::Type::Pointer: 1793 if (pointee_or_element_clang_type) 1794 *pointee_or_element_clang_type = qual_type->getPointeeType().getAsOpaquePtr(); 1795 return eTypeHasChildren | eTypeIsPointer | eTypeHasValue; 1796 1797 case clang::Type::Record: 1798 if (qual_type->getAsCXXRecordDecl()) 1799 return eTypeHasChildren | eTypeIsClass | eTypeIsCPlusPlus; 1800 else 1801 return eTypeHasChildren | eTypeIsStructUnion; 1802 break; 1803 case clang::Type::SubstTemplateTypeParm: return eTypeIsTemplate; 1804 case clang::Type::TemplateTypeParm: return eTypeIsTemplate; 1805 case clang::Type::TemplateSpecialization: return eTypeIsTemplate; 1806 1807 case clang::Type::Typedef: 1808 return eTypeIsTypedef | ClangASTContext::GetTypeInfo (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), 1809 ast_context, 1810 pointee_or_element_clang_type); 1811 1812 case clang::Type::TypeOfExpr: return 0; 1813 case clang::Type::TypeOf: return 0; 1814 case clang::Type::UnresolvedUsing: return 0; 1815 case clang::Type::Vector: return eTypeHasChildren | eTypeIsVector; 1816 default: return 0; 1817 } 1818 return 0; 1819} 1820 1821 1822#pragma mark Aggregate Types 1823 1824bool 1825ClangASTContext::IsAggregateType (clang_type_t clang_type) 1826{ 1827 if (clang_type == NULL) 1828 return false; 1829 1830 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 1831 1832 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 1833 switch (type_class) 1834 { 1835 case clang::Type::IncompleteArray: 1836 case clang::Type::VariableArray: 1837 case clang::Type::ConstantArray: 1838 case clang::Type::ExtVector: 1839 case clang::Type::Vector: 1840 case clang::Type::Record: 1841 case clang::Type::ObjCObject: 1842 case clang::Type::ObjCInterface: 1843 return true; 1844 1845 case clang::Type::Typedef: 1846 return ClangASTContext::IsAggregateType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr()); 1847 1848 default: 1849 break; 1850 } 1851 // The clang type does have a value 1852 return false; 1853} 1854 1855uint32_t 1856ClangASTContext::GetNumChildren (clang_type_t clang_qual_type, bool omit_empty_base_classes) 1857{ 1858 if (clang_qual_type == NULL) 1859 return 0; 1860 1861 uint32_t num_children = 0; 1862 QualType qual_type(QualType::getFromOpaquePtr(clang_qual_type)); 1863 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 1864 switch (type_class) 1865 { 1866 case clang::Type::Builtin: 1867 switch (cast<clang::BuiltinType>(qual_type)->getKind()) 1868 { 1869 case clang::BuiltinType::ObjCId: // child is Class 1870 case clang::BuiltinType::ObjCClass: // child is Class 1871 num_children = 1; 1872 break; 1873 1874 default: 1875 break; 1876 } 1877 break; 1878 1879 case clang::Type::Record: 1880 if (ClangASTType::IsDefined (clang_qual_type)) 1881 { 1882 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); 1883 const RecordDecl *record_decl = record_type->getDecl(); 1884 assert(record_decl); 1885 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 1886 if (cxx_record_decl) 1887 { 1888 if (omit_empty_base_classes) 1889 { 1890 // Check each base classes to see if it or any of its 1891 // base classes contain any fields. This can help 1892 // limit the noise in variable views by not having to 1893 // show base classes that contain no members. 1894 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 1895 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 1896 base_class != base_class_end; 1897 ++base_class) 1898 { 1899 const CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 1900 1901 // Skip empty base classes 1902 if (RecordHasFields(base_class_decl) == false) 1903 continue; 1904 1905 num_children++; 1906 } 1907 } 1908 else 1909 { 1910 // Include all base classes 1911 num_children += cxx_record_decl->getNumBases(); 1912 } 1913 1914 } 1915 RecordDecl::field_iterator field, field_end; 1916 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field) 1917 ++num_children; 1918 } 1919 break; 1920 1921 case clang::Type::ObjCObject: 1922 case clang::Type::ObjCInterface: 1923 { 1924 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); 1925 assert (objc_class_type); 1926 if (objc_class_type) 1927 { 1928 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 1929 1930 if (class_interface_decl) 1931 { 1932 1933 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); 1934 if (superclass_interface_decl) 1935 { 1936 if (omit_empty_base_classes) 1937 { 1938 if (ClangASTContext::ObjCDeclHasIVars (superclass_interface_decl, true)) 1939 ++num_children; 1940 } 1941 else 1942 ++num_children; 1943 } 1944 1945 num_children += class_interface_decl->ivar_size(); 1946 } 1947 } 1948 } 1949 break; 1950 1951 case clang::Type::ObjCObjectPointer: 1952 { 1953 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(qual_type.getTypePtr()); 1954 QualType pointee_type = pointer_type->getPointeeType(); 1955 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(), 1956 omit_empty_base_classes); 1957 // If this type points to a simple type, then it has 1 child 1958 if (num_pointee_children == 0) 1959 num_children = 1; 1960 else 1961 num_children = num_pointee_children; 1962 } 1963 break; 1964 1965 case clang::Type::ConstantArray: 1966 num_children = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue(); 1967 break; 1968 1969 case clang::Type::Pointer: 1970 { 1971 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); 1972 QualType pointee_type = pointer_type->getPointeeType(); 1973 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(), 1974 omit_empty_base_classes); 1975 // If this type points to a simple type, then it has 1 child 1976 if (num_pointee_children == 0) 1977 num_children = 1; 1978 else 1979 num_children = num_pointee_children; 1980 } 1981 break; 1982 1983 case clang::Type::LValueReference: 1984 case clang::Type::RValueReference: 1985 { 1986 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); 1987 QualType pointee_type = reference_type->getPointeeType(); 1988 uint32_t num_pointee_children = ClangASTContext::GetNumChildren (pointee_type.getAsOpaquePtr(), 1989 omit_empty_base_classes); 1990 // If this type points to a simple type, then it has 1 child 1991 if (num_pointee_children == 0) 1992 num_children = 1; 1993 else 1994 num_children = num_pointee_children; 1995 } 1996 break; 1997 1998 1999 case clang::Type::Typedef: 2000 num_children = ClangASTContext::GetNumChildren (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), omit_empty_base_classes); 2001 break; 2002 2003 default: 2004 break; 2005 } 2006 return num_children; 2007} 2008 2009 2010clang_type_t 2011ClangASTContext::GetChildClangTypeAtIndex 2012( 2013 const char *parent_name, 2014 clang_type_t parent_clang_type, 2015 uint32_t idx, 2016 bool transparent_pointers, 2017 bool omit_empty_base_classes, 2018 std::string& child_name, 2019 uint32_t &child_byte_size, 2020 int32_t &child_byte_offset, 2021 uint32_t &child_bitfield_bit_size, 2022 uint32_t &child_bitfield_bit_offset, 2023 bool &child_is_base_class 2024) 2025{ 2026 if (parent_clang_type) 2027 2028 return GetChildClangTypeAtIndex (getASTContext(), 2029 parent_name, 2030 parent_clang_type, 2031 idx, 2032 transparent_pointers, 2033 omit_empty_base_classes, 2034 child_name, 2035 child_byte_size, 2036 child_byte_offset, 2037 child_bitfield_bit_size, 2038 child_bitfield_bit_offset, 2039 child_is_base_class); 2040 return NULL; 2041} 2042 2043clang_type_t 2044ClangASTContext::GetChildClangTypeAtIndex 2045( 2046 ASTContext *ast_context, 2047 const char *parent_name, 2048 clang_type_t parent_clang_type, 2049 uint32_t idx, 2050 bool transparent_pointers, 2051 bool omit_empty_base_classes, 2052 std::string& child_name, 2053 uint32_t &child_byte_size, 2054 int32_t &child_byte_offset, 2055 uint32_t &child_bitfield_bit_size, 2056 uint32_t &child_bitfield_bit_offset, 2057 bool &child_is_base_class 2058) 2059{ 2060 if (parent_clang_type == NULL) 2061 return NULL; 2062 2063 if (idx < ClangASTContext::GetNumChildren (parent_clang_type, omit_empty_base_classes)) 2064 { 2065 uint32_t bit_offset; 2066 child_bitfield_bit_size = 0; 2067 child_bitfield_bit_offset = 0; 2068 child_is_base_class = false; 2069 QualType parent_qual_type(QualType::getFromOpaquePtr(parent_clang_type)); 2070 const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass(); 2071 switch (parent_type_class) 2072 { 2073 case clang::Type::Builtin: 2074 switch (cast<clang::BuiltinType>(parent_qual_type)->getKind()) 2075 { 2076 case clang::BuiltinType::ObjCId: 2077 case clang::BuiltinType::ObjCClass: 2078 child_name = "isa"; 2079 child_byte_size = ast_context->getTypeSize(ast_context->ObjCBuiltinClassTy) / CHAR_BIT; 2080 return ast_context->ObjCBuiltinClassTy.getAsOpaquePtr(); 2081 2082 default: 2083 break; 2084 } 2085 break; 2086 2087 2088 case clang::Type::Record: 2089 { 2090 const RecordType *record_type = cast<RecordType>(parent_qual_type.getTypePtr()); 2091 const RecordDecl *record_decl = record_type->getDecl(); 2092 assert(record_decl); 2093 const ASTRecordLayout &record_layout = ast_context->getASTRecordLayout(record_decl); 2094 uint32_t child_idx = 0; 2095 2096 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 2097 if (cxx_record_decl) 2098 { 2099 // We might have base classes to print out first 2100 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 2101 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 2102 base_class != base_class_end; 2103 ++base_class) 2104 { 2105 const CXXRecordDecl *base_class_decl = NULL; 2106 2107 // Skip empty base classes 2108 if (omit_empty_base_classes) 2109 { 2110 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 2111 if (RecordHasFields(base_class_decl) == false) 2112 continue; 2113 } 2114 2115 if (idx == child_idx) 2116 { 2117 if (base_class_decl == NULL) 2118 base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 2119 2120 2121 if (base_class->isVirtual()) 2122 bit_offset = record_layout.getVBaseClassOffset(base_class_decl).getQuantity(); 2123 else 2124 bit_offset = record_layout.getBaseClassOffset(base_class_decl).getQuantity(); 2125 2126 // Base classes should be a multiple of 8 bits in size 2127 assert (bit_offset % 8 == 0); 2128 child_byte_offset = bit_offset/8; 2129 std::string base_class_type_name(base_class->getType().getAsString()); 2130 2131 child_name.assign(base_class_type_name.c_str()); 2132 2133 uint64_t clang_type_info_bit_size = ast_context->getTypeSize(base_class->getType()); 2134 2135 // Base classes biut sizes should be a multiple of 8 bits in size 2136 assert (clang_type_info_bit_size % 8 == 0); 2137 child_byte_size = clang_type_info_bit_size / 8; 2138 child_is_base_class = true; 2139 return base_class->getType().getAsOpaquePtr(); 2140 } 2141 // We don't increment the child index in the for loop since we might 2142 // be skipping empty base classes 2143 ++child_idx; 2144 } 2145 } 2146 // Make sure index is in range... 2147 uint32_t field_idx = 0; 2148 RecordDecl::field_iterator field, field_end; 2149 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx, ++child_idx) 2150 { 2151 if (idx == child_idx) 2152 { 2153 // Print the member type if requested 2154 // Print the member name and equal sign 2155 child_name.assign(field->getNameAsString().c_str()); 2156 2157 // Figure out the type byte size (field_type_info.first) and 2158 // alignment (field_type_info.second) from the AST context. 2159 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(field->getType()); 2160 assert(field_idx < record_layout.getFieldCount()); 2161 2162 child_byte_size = field_type_info.first / 8; 2163 2164 // Figure out the field offset within the current struct/union/class type 2165 bit_offset = record_layout.getFieldOffset (field_idx); 2166 child_byte_offset = bit_offset / 8; 2167 if (ClangASTContext::FieldIsBitfield (ast_context, *field, child_bitfield_bit_size)) 2168 child_bitfield_bit_offset = bit_offset % 8; 2169 2170 return field->getType().getAsOpaquePtr(); 2171 } 2172 } 2173 } 2174 break; 2175 2176 case clang::Type::ObjCObject: 2177 case clang::Type::ObjCInterface: 2178 { 2179 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(parent_qual_type.getTypePtr()); 2180 assert (objc_class_type); 2181 if (objc_class_type) 2182 { 2183 uint32_t child_idx = 0; 2184 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 2185 2186 if (class_interface_decl) 2187 { 2188 2189 const ASTRecordLayout &interface_layout = ast_context->getASTObjCInterfaceLayout(class_interface_decl); 2190 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); 2191 if (superclass_interface_decl) 2192 { 2193 if (omit_empty_base_classes) 2194 { 2195 if (ClangASTContext::GetNumChildren(ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), omit_empty_base_classes) > 0) 2196 { 2197 if (idx == 0) 2198 { 2199 QualType ivar_qual_type(ast_context->getObjCInterfaceType(superclass_interface_decl)); 2200 2201 2202 child_name.assign(superclass_interface_decl->getNameAsString().c_str()); 2203 2204 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr()); 2205 2206 child_byte_size = ivar_type_info.first / 8; 2207 child_byte_offset = 0; 2208 child_is_base_class = true; 2209 2210 return ivar_qual_type.getAsOpaquePtr(); 2211 } 2212 2213 ++child_idx; 2214 } 2215 } 2216 else 2217 ++child_idx; 2218 } 2219 2220 const uint32_t superclass_idx = child_idx; 2221 2222 if (idx < (child_idx + class_interface_decl->ivar_size())) 2223 { 2224 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); 2225 2226 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos) 2227 { 2228 if (child_idx == idx) 2229 { 2230 const ObjCIvarDecl* ivar_decl = *ivar_pos; 2231 2232 QualType ivar_qual_type(ivar_decl->getType()); 2233 2234 child_name.assign(ivar_decl->getNameAsString().c_str()); 2235 2236 std::pair<uint64_t, unsigned> ivar_type_info = ast_context->getTypeInfo(ivar_qual_type.getTypePtr()); 2237 2238 child_byte_size = ivar_type_info.first / 8; 2239 2240 // Figure out the field offset within the current struct/union/class type 2241 bit_offset = interface_layout.getFieldOffset (child_idx - superclass_idx); 2242 child_byte_offset = bit_offset / 8; 2243 2244 return ivar_qual_type.getAsOpaquePtr(); 2245 } 2246 ++child_idx; 2247 } 2248 } 2249 } 2250 } 2251 } 2252 break; 2253 2254 case clang::Type::ObjCObjectPointer: 2255 { 2256 ObjCObjectPointerType *pointer_type = cast<ObjCObjectPointerType>(parent_qual_type.getTypePtr()); 2257 QualType pointee_type = pointer_type->getPointeeType(); 2258 2259 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 2260 { 2261 return GetChildClangTypeAtIndex (ast_context, 2262 parent_name, 2263 pointer_type->getPointeeType().getAsOpaquePtr(), 2264 idx, 2265 transparent_pointers, 2266 omit_empty_base_classes, 2267 child_name, 2268 child_byte_size, 2269 child_byte_offset, 2270 child_bitfield_bit_size, 2271 child_bitfield_bit_offset, 2272 child_is_base_class); 2273 } 2274 else 2275 { 2276 if (parent_name) 2277 { 2278 child_name.assign(1, '*'); 2279 child_name += parent_name; 2280 } 2281 2282 // We have a pointer to an simple type 2283 if (idx == 0) 2284 { 2285 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type); 2286 assert(clang_type_info.first % 8 == 0); 2287 child_byte_size = clang_type_info.first / 8; 2288 child_byte_offset = 0; 2289 return pointee_type.getAsOpaquePtr(); 2290 } 2291 } 2292 } 2293 break; 2294 2295 case clang::Type::ConstantArray: 2296 { 2297 const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr()); 2298 const uint64_t element_count = array->getSize().getLimitedValue(); 2299 2300 if (idx < element_count) 2301 { 2302 std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType()); 2303 2304 char element_name[64]; 2305 ::snprintf (element_name, sizeof (element_name), "[%u]", idx); 2306 2307 child_name.assign(element_name); 2308 assert(field_type_info.first % 8 == 0); 2309 child_byte_size = field_type_info.first / 8; 2310 child_byte_offset = idx * child_byte_size; 2311 return array->getElementType().getAsOpaquePtr(); 2312 } 2313 } 2314 break; 2315 2316 case clang::Type::Pointer: 2317 { 2318 PointerType *pointer_type = cast<PointerType>(parent_qual_type.getTypePtr()); 2319 QualType pointee_type = pointer_type->getPointeeType(); 2320 2321 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 2322 { 2323 return GetChildClangTypeAtIndex (ast_context, 2324 parent_name, 2325 pointer_type->getPointeeType().getAsOpaquePtr(), 2326 idx, 2327 transparent_pointers, 2328 omit_empty_base_classes, 2329 child_name, 2330 child_byte_size, 2331 child_byte_offset, 2332 child_bitfield_bit_size, 2333 child_bitfield_bit_offset, 2334 child_is_base_class); 2335 } 2336 else 2337 { 2338 if (parent_name) 2339 { 2340 child_name.assign(1, '*'); 2341 child_name += parent_name; 2342 } 2343 2344 // We have a pointer to an simple type 2345 if (idx == 0) 2346 { 2347 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type); 2348 assert(clang_type_info.first % 8 == 0); 2349 child_byte_size = clang_type_info.first / 8; 2350 child_byte_offset = 0; 2351 return pointee_type.getAsOpaquePtr(); 2352 } 2353 } 2354 } 2355 break; 2356 2357 case clang::Type::LValueReference: 2358 case clang::Type::RValueReference: 2359 { 2360 ReferenceType *reference_type = cast<ReferenceType>(parent_qual_type.getTypePtr()); 2361 QualType pointee_type(reference_type->getPointeeType()); 2362 clang_type_t pointee_clang_type = pointee_type.getAsOpaquePtr(); 2363 if (transparent_pointers && ClangASTContext::IsAggregateType (pointee_clang_type)) 2364 { 2365 return GetChildClangTypeAtIndex (ast_context, 2366 parent_name, 2367 pointee_clang_type, 2368 idx, 2369 transparent_pointers, 2370 omit_empty_base_classes, 2371 child_name, 2372 child_byte_size, 2373 child_byte_offset, 2374 child_bitfield_bit_size, 2375 child_bitfield_bit_offset, 2376 child_is_base_class); 2377 } 2378 else 2379 { 2380 if (parent_name) 2381 { 2382 child_name.assign(1, '&'); 2383 child_name += parent_name; 2384 } 2385 2386 // We have a pointer to an simple type 2387 if (idx == 0) 2388 { 2389 std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type); 2390 assert(clang_type_info.first % 8 == 0); 2391 child_byte_size = clang_type_info.first / 8; 2392 child_byte_offset = 0; 2393 return pointee_type.getAsOpaquePtr(); 2394 } 2395 } 2396 } 2397 break; 2398 2399 case clang::Type::Typedef: 2400 return GetChildClangTypeAtIndex (ast_context, 2401 parent_name, 2402 cast<TypedefType>(parent_qual_type)->LookThroughTypedefs().getAsOpaquePtr(), 2403 idx, 2404 transparent_pointers, 2405 omit_empty_base_classes, 2406 child_name, 2407 child_byte_size, 2408 child_byte_offset, 2409 child_bitfield_bit_size, 2410 child_bitfield_bit_offset, 2411 child_is_base_class); 2412 break; 2413 2414 default: 2415 break; 2416 } 2417 } 2418 return NULL; 2419} 2420 2421static inline bool 2422BaseSpecifierIsEmpty (const CXXBaseSpecifier *b) 2423{ 2424 return ClangASTContext::RecordHasFields(cast<CXXRecordDecl>(b->getType()->getAs<RecordType>()->getDecl())) == false; 2425} 2426 2427static uint32_t 2428GetNumBaseClasses (const CXXRecordDecl *cxx_record_decl, bool omit_empty_base_classes) 2429{ 2430 uint32_t num_bases = 0; 2431 if (cxx_record_decl) 2432 { 2433 if (omit_empty_base_classes) 2434 { 2435 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 2436 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 2437 base_class != base_class_end; 2438 ++base_class) 2439 { 2440 // Skip empty base classes 2441 if (omit_empty_base_classes) 2442 { 2443 if (BaseSpecifierIsEmpty (base_class)) 2444 continue; 2445 } 2446 ++num_bases; 2447 } 2448 } 2449 else 2450 num_bases = cxx_record_decl->getNumBases(); 2451 } 2452 return num_bases; 2453} 2454 2455 2456static uint32_t 2457GetIndexForRecordBase 2458( 2459 const RecordDecl *record_decl, 2460 const CXXBaseSpecifier *base_spec, 2461 bool omit_empty_base_classes 2462) 2463{ 2464 uint32_t child_idx = 0; 2465 2466 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 2467 2468// const char *super_name = record_decl->getNameAsCString(); 2469// const char *base_name = base_spec->getType()->getAs<RecordType>()->getDecl()->getNameAsCString(); 2470// printf ("GetIndexForRecordChild (%s, %s)\n", super_name, base_name); 2471// 2472 if (cxx_record_decl) 2473 { 2474 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 2475 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 2476 base_class != base_class_end; 2477 ++base_class) 2478 { 2479 if (omit_empty_base_classes) 2480 { 2481 if (BaseSpecifierIsEmpty (base_class)) 2482 continue; 2483 } 2484 2485// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", super_name, base_name, 2486// child_idx, 2487// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString()); 2488// 2489// 2490 if (base_class == base_spec) 2491 return child_idx; 2492 ++child_idx; 2493 } 2494 } 2495 2496 return UINT32_MAX; 2497} 2498 2499 2500static uint32_t 2501GetIndexForRecordChild 2502( 2503 const RecordDecl *record_decl, 2504 NamedDecl *canonical_decl, 2505 bool omit_empty_base_classes 2506) 2507{ 2508 uint32_t child_idx = GetNumBaseClasses (dyn_cast<CXXRecordDecl>(record_decl), omit_empty_base_classes); 2509 2510// const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 2511// 2512//// printf ("GetIndexForRecordChild (%s, %s)\n", record_decl->getNameAsCString(), canonical_decl->getNameAsCString()); 2513// if (cxx_record_decl) 2514// { 2515// CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 2516// for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 2517// base_class != base_class_end; 2518// ++base_class) 2519// { 2520// if (omit_empty_base_classes) 2521// { 2522// if (BaseSpecifierIsEmpty (base_class)) 2523// continue; 2524// } 2525// 2526//// printf ("GetIndexForRecordChild (%s, %s) base[%u] = %s\n", 2527//// record_decl->getNameAsCString(), 2528//// canonical_decl->getNameAsCString(), 2529//// child_idx, 2530//// base_class->getType()->getAs<RecordType>()->getDecl()->getNameAsCString()); 2531// 2532// 2533// CXXRecordDecl *curr_base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 2534// if (curr_base_class_decl == canonical_decl) 2535// { 2536// return child_idx; 2537// } 2538// ++child_idx; 2539// } 2540// } 2541// 2542// const uint32_t num_bases = child_idx; 2543 RecordDecl::field_iterator field, field_end; 2544 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); 2545 field != field_end; 2546 ++field, ++child_idx) 2547 { 2548// printf ("GetIndexForRecordChild (%s, %s) field[%u] = %s\n", 2549// record_decl->getNameAsCString(), 2550// canonical_decl->getNameAsCString(), 2551// child_idx - num_bases, 2552// field->getNameAsCString()); 2553 2554 if (field->getCanonicalDecl() == canonical_decl) 2555 return child_idx; 2556 } 2557 2558 return UINT32_MAX; 2559} 2560 2561// Look for a child member (doesn't include base classes, but it does include 2562// their members) in the type hierarchy. Returns an index path into "clang_type" 2563// on how to reach the appropriate member. 2564// 2565// class A 2566// { 2567// public: 2568// int m_a; 2569// int m_b; 2570// }; 2571// 2572// class B 2573// { 2574// }; 2575// 2576// class C : 2577// public B, 2578// public A 2579// { 2580// }; 2581// 2582// If we have a clang type that describes "class C", and we wanted to looked 2583// "m_b" in it: 2584// 2585// With omit_empty_base_classes == false we would get an integer array back with: 2586// { 1, 1 } 2587// The first index 1 is the child index for "class A" within class C 2588// The second index 1 is the child index for "m_b" within class A 2589// 2590// With omit_empty_base_classes == true we would get an integer array back with: 2591// { 0, 1 } 2592// The first index 0 is the child index for "class A" within class C (since class B doesn't have any members it doesn't count) 2593// The second index 1 is the child index for "m_b" within class A 2594 2595size_t 2596ClangASTContext::GetIndexOfChildMemberWithName 2597( 2598 ASTContext *ast_context, 2599 clang_type_t clang_type, 2600 const char *name, 2601 bool omit_empty_base_classes, 2602 std::vector<uint32_t>& child_indexes 2603) 2604{ 2605 if (clang_type && name && name[0]) 2606 { 2607 QualType qual_type(QualType::getFromOpaquePtr(clang_type)); 2608 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 2609 switch (type_class) 2610 { 2611 case clang::Type::Record: 2612 { 2613 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); 2614 const RecordDecl *record_decl = record_type->getDecl(); 2615 2616 assert(record_decl); 2617 uint32_t child_idx = 0; 2618 2619 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 2620 2621 // Try and find a field that matches NAME 2622 RecordDecl::field_iterator field, field_end; 2623 StringRef name_sref(name); 2624 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); 2625 field != field_end; 2626 ++field, ++child_idx) 2627 { 2628 if (field->getName().equals (name_sref)) 2629 { 2630 // We have to add on the number of base classes to this index! 2631 child_indexes.push_back (child_idx + GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes)); 2632 return child_indexes.size(); 2633 } 2634 } 2635 2636 if (cxx_record_decl) 2637 { 2638 const RecordDecl *parent_record_decl = cxx_record_decl; 2639 2640 //printf ("parent = %s\n", parent_record_decl->getNameAsCString()); 2641 2642 //const Decl *root_cdecl = cxx_record_decl->getCanonicalDecl(); 2643 // Didn't find things easily, lets let clang do its thang... 2644 IdentifierInfo & ident_ref = ast_context->Idents.get(name, name + strlen (name)); 2645 DeclarationName decl_name(&ident_ref); 2646 2647 CXXBasePaths paths; 2648 if (cxx_record_decl->lookupInBases(CXXRecordDecl::FindOrdinaryMember, 2649 decl_name.getAsOpaquePtr(), 2650 paths)) 2651 { 2652 CXXBasePaths::const_paths_iterator path, path_end = paths.end(); 2653 for (path = paths.begin(); path != path_end; ++path) 2654 { 2655 const size_t num_path_elements = path->size(); 2656 for (size_t e=0; e<num_path_elements; ++e) 2657 { 2658 CXXBasePathElement elem = (*path)[e]; 2659 2660 child_idx = GetIndexForRecordBase (parent_record_decl, elem.Base, omit_empty_base_classes); 2661 if (child_idx == UINT32_MAX) 2662 { 2663 child_indexes.clear(); 2664 return 0; 2665 } 2666 else 2667 { 2668 child_indexes.push_back (child_idx); 2669 parent_record_decl = cast<RecordDecl>(elem.Base->getType()->getAs<RecordType>()->getDecl()); 2670 } 2671 } 2672 DeclContext::lookup_iterator named_decl_pos; 2673 for (named_decl_pos = path->Decls.first; 2674 named_decl_pos != path->Decls.second && parent_record_decl; 2675 ++named_decl_pos) 2676 { 2677 //printf ("path[%zu] = %s\n", child_indexes.size(), (*named_decl_pos)->getNameAsCString()); 2678 2679 child_idx = GetIndexForRecordChild (parent_record_decl, *named_decl_pos, omit_empty_base_classes); 2680 if (child_idx == UINT32_MAX) 2681 { 2682 child_indexes.clear(); 2683 return 0; 2684 } 2685 else 2686 { 2687 child_indexes.push_back (child_idx); 2688 } 2689 } 2690 } 2691 return child_indexes.size(); 2692 } 2693 } 2694 2695 } 2696 break; 2697 2698 case clang::Type::ObjCObject: 2699 case clang::Type::ObjCInterface: 2700 { 2701 StringRef name_sref(name); 2702 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); 2703 assert (objc_class_type); 2704 if (objc_class_type) 2705 { 2706 uint32_t child_idx = 0; 2707 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 2708 2709 if (class_interface_decl) 2710 { 2711 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); 2712 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); 2713 2714 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos, ++child_idx) 2715 { 2716 const ObjCIvarDecl* ivar_decl = *ivar_pos; 2717 2718 if (ivar_decl->getName().equals (name_sref)) 2719 { 2720 if ((!omit_empty_base_classes && superclass_interface_decl) || 2721 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true))) 2722 ++child_idx; 2723 2724 child_indexes.push_back (child_idx); 2725 return child_indexes.size(); 2726 } 2727 } 2728 2729 if (superclass_interface_decl) 2730 { 2731 // The super class index is always zero for ObjC classes, 2732 // so we push it onto the child indexes in case we find 2733 // an ivar in our superclass... 2734 child_indexes.push_back (0); 2735 2736 if (GetIndexOfChildMemberWithName (ast_context, 2737 ast_context->getObjCInterfaceType(superclass_interface_decl).getAsOpaquePtr(), 2738 name, 2739 omit_empty_base_classes, 2740 child_indexes)) 2741 { 2742 // We did find an ivar in a superclass so just 2743 // return the results! 2744 return child_indexes.size(); 2745 } 2746 2747 // We didn't find an ivar matching "name" in our 2748 // superclass, pop the superclass zero index that 2749 // we pushed on above. 2750 child_indexes.pop_back(); 2751 } 2752 } 2753 } 2754 } 2755 break; 2756 2757 case clang::Type::ObjCObjectPointer: 2758 { 2759 return GetIndexOfChildMemberWithName (ast_context, 2760 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(), 2761 name, 2762 omit_empty_base_classes, 2763 child_indexes); 2764 } 2765 break; 2766 2767 2768 case clang::Type::ConstantArray: 2769 { 2770// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr()); 2771// const uint64_t element_count = array->getSize().getLimitedValue(); 2772// 2773// if (idx < element_count) 2774// { 2775// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType()); 2776// 2777// char element_name[32]; 2778// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx); 2779// 2780// child_name.assign(element_name); 2781// assert(field_type_info.first % 8 == 0); 2782// child_byte_size = field_type_info.first / 8; 2783// child_byte_offset = idx * child_byte_size; 2784// return array->getElementType().getAsOpaquePtr(); 2785// } 2786 } 2787 break; 2788 2789// case clang::Type::MemberPointerType: 2790// { 2791// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr()); 2792// QualType pointee_type = mem_ptr_type->getPointeeType(); 2793// 2794// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 2795// { 2796// return GetIndexOfChildWithName (ast_context, 2797// mem_ptr_type->getPointeeType().getAsOpaquePtr(), 2798// name); 2799// } 2800// } 2801// break; 2802// 2803 case clang::Type::LValueReference: 2804 case clang::Type::RValueReference: 2805 { 2806 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); 2807 QualType pointee_type = reference_type->getPointeeType(); 2808 2809 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 2810 { 2811 return GetIndexOfChildMemberWithName (ast_context, 2812 reference_type->getPointeeType().getAsOpaquePtr(), 2813 name, 2814 omit_empty_base_classes, 2815 child_indexes); 2816 } 2817 } 2818 break; 2819 2820 case clang::Type::Pointer: 2821 { 2822 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); 2823 QualType pointee_type = pointer_type->getPointeeType(); 2824 2825 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 2826 { 2827 return GetIndexOfChildMemberWithName (ast_context, 2828 pointer_type->getPointeeType().getAsOpaquePtr(), 2829 name, 2830 omit_empty_base_classes, 2831 child_indexes); 2832 } 2833 else 2834 { 2835// if (parent_name) 2836// { 2837// child_name.assign(1, '*'); 2838// child_name += parent_name; 2839// } 2840// 2841// // We have a pointer to an simple type 2842// if (idx == 0) 2843// { 2844// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type); 2845// assert(clang_type_info.first % 8 == 0); 2846// child_byte_size = clang_type_info.first / 8; 2847// child_byte_offset = 0; 2848// return pointee_type.getAsOpaquePtr(); 2849// } 2850 } 2851 } 2852 break; 2853 2854 case clang::Type::Typedef: 2855 return GetIndexOfChildMemberWithName (ast_context, 2856 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), 2857 name, 2858 omit_empty_base_classes, 2859 child_indexes); 2860 2861 default: 2862 break; 2863 } 2864 } 2865 return 0; 2866} 2867 2868 2869// Get the index of the child of "clang_type" whose name matches. This function 2870// doesn't descend into the children, but only looks one level deep and name 2871// matches can include base class names. 2872 2873uint32_t 2874ClangASTContext::GetIndexOfChildWithName 2875( 2876 ASTContext *ast_context, 2877 clang_type_t clang_type, 2878 const char *name, 2879 bool omit_empty_base_classes 2880) 2881{ 2882 if (clang_type && name && name[0]) 2883 { 2884 QualType qual_type(QualType::getFromOpaquePtr(clang_type)); 2885 2886 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 2887 2888 switch (type_class) 2889 { 2890 case clang::Type::Record: 2891 { 2892 const RecordType *record_type = cast<RecordType>(qual_type.getTypePtr()); 2893 const RecordDecl *record_decl = record_type->getDecl(); 2894 2895 assert(record_decl); 2896 uint32_t child_idx = 0; 2897 2898 const CXXRecordDecl *cxx_record_decl = dyn_cast<CXXRecordDecl>(record_decl); 2899 2900 if (cxx_record_decl) 2901 { 2902 CXXRecordDecl::base_class_const_iterator base_class, base_class_end; 2903 for (base_class = cxx_record_decl->bases_begin(), base_class_end = cxx_record_decl->bases_end(); 2904 base_class != base_class_end; 2905 ++base_class) 2906 { 2907 // Skip empty base classes 2908 CXXRecordDecl *base_class_decl = cast<CXXRecordDecl>(base_class->getType()->getAs<RecordType>()->getDecl()); 2909 if (omit_empty_base_classes && RecordHasFields(base_class_decl) == false) 2910 continue; 2911 2912 if (base_class->getType().getAsString().compare (name) == 0) 2913 return child_idx; 2914 ++child_idx; 2915 } 2916 } 2917 2918 // Try and find a field that matches NAME 2919 RecordDecl::field_iterator field, field_end; 2920 StringRef name_sref(name); 2921 for (field = record_decl->field_begin(), field_end = record_decl->field_end(); 2922 field != field_end; 2923 ++field, ++child_idx) 2924 { 2925 if (field->getName().equals (name_sref)) 2926 return child_idx; 2927 } 2928 2929 } 2930 break; 2931 2932 case clang::Type::ObjCObject: 2933 case clang::Type::ObjCInterface: 2934 { 2935 StringRef name_sref(name); 2936 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type.getTypePtr()); 2937 assert (objc_class_type); 2938 if (objc_class_type) 2939 { 2940 uint32_t child_idx = 0; 2941 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 2942 2943 if (class_interface_decl) 2944 { 2945 ObjCInterfaceDecl::ivar_iterator ivar_pos, ivar_end = class_interface_decl->ivar_end(); 2946 ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass(); 2947 2948 for (ivar_pos = class_interface_decl->ivar_begin(); ivar_pos != ivar_end; ++ivar_pos) 2949 { 2950 const ObjCIvarDecl* ivar_decl = *ivar_pos; 2951 2952 if (ivar_decl->getName().equals (name_sref)) 2953 { 2954 if ((!omit_empty_base_classes && superclass_interface_decl) || 2955 ( omit_empty_base_classes && ObjCDeclHasIVars (superclass_interface_decl, true))) 2956 ++child_idx; 2957 2958 return child_idx; 2959 } 2960 } 2961 2962 if (superclass_interface_decl) 2963 { 2964 if (superclass_interface_decl->getName().equals (name_sref)) 2965 return 0; 2966 } 2967 } 2968 } 2969 } 2970 break; 2971 2972 case clang::Type::ObjCObjectPointer: 2973 { 2974 return GetIndexOfChildWithName (ast_context, 2975 cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr(), 2976 name, 2977 omit_empty_base_classes); 2978 } 2979 break; 2980 2981 case clang::Type::ConstantArray: 2982 { 2983// const ConstantArrayType *array = cast<ConstantArrayType>(parent_qual_type.getTypePtr()); 2984// const uint64_t element_count = array->getSize().getLimitedValue(); 2985// 2986// if (idx < element_count) 2987// { 2988// std::pair<uint64_t, unsigned> field_type_info = ast_context->getTypeInfo(array->getElementType()); 2989// 2990// char element_name[32]; 2991// ::snprintf (element_name, sizeof (element_name), "%s[%u]", parent_name ? parent_name : "", idx); 2992// 2993// child_name.assign(element_name); 2994// assert(field_type_info.first % 8 == 0); 2995// child_byte_size = field_type_info.first / 8; 2996// child_byte_offset = idx * child_byte_size; 2997// return array->getElementType().getAsOpaquePtr(); 2998// } 2999 } 3000 break; 3001 3002// case clang::Type::MemberPointerType: 3003// { 3004// MemberPointerType *mem_ptr_type = cast<MemberPointerType>(qual_type.getTypePtr()); 3005// QualType pointee_type = mem_ptr_type->getPointeeType(); 3006// 3007// if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 3008// { 3009// return GetIndexOfChildWithName (ast_context, 3010// mem_ptr_type->getPointeeType().getAsOpaquePtr(), 3011// name); 3012// } 3013// } 3014// break; 3015// 3016 case clang::Type::LValueReference: 3017 case clang::Type::RValueReference: 3018 { 3019 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); 3020 QualType pointee_type = reference_type->getPointeeType(); 3021 3022 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 3023 { 3024 return GetIndexOfChildWithName (ast_context, 3025 reference_type->getPointeeType().getAsOpaquePtr(), 3026 name, 3027 omit_empty_base_classes); 3028 } 3029 } 3030 break; 3031 3032 case clang::Type::Pointer: 3033 { 3034 PointerType *pointer_type = cast<PointerType>(qual_type.getTypePtr()); 3035 QualType pointee_type = pointer_type->getPointeeType(); 3036 3037 if (ClangASTContext::IsAggregateType (pointee_type.getAsOpaquePtr())) 3038 { 3039 return GetIndexOfChildWithName (ast_context, 3040 pointer_type->getPointeeType().getAsOpaquePtr(), 3041 name, 3042 omit_empty_base_classes); 3043 } 3044 else 3045 { 3046// if (parent_name) 3047// { 3048// child_name.assign(1, '*'); 3049// child_name += parent_name; 3050// } 3051// 3052// // We have a pointer to an simple type 3053// if (idx == 0) 3054// { 3055// std::pair<uint64_t, unsigned> clang_type_info = ast_context->getTypeInfo(pointee_type); 3056// assert(clang_type_info.first % 8 == 0); 3057// child_byte_size = clang_type_info.first / 8; 3058// child_byte_offset = 0; 3059// return pointee_type.getAsOpaquePtr(); 3060// } 3061 } 3062 } 3063 break; 3064 3065 case clang::Type::Typedef: 3066 return GetIndexOfChildWithName (ast_context, 3067 cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), 3068 name, 3069 omit_empty_base_classes); 3070 3071 default: 3072 break; 3073 } 3074 } 3075 return UINT32_MAX; 3076} 3077 3078#pragma mark TagType 3079 3080bool 3081ClangASTContext::SetTagTypeKind (clang_type_t tag_clang_type, int kind) 3082{ 3083 if (tag_clang_type) 3084 { 3085 QualType tag_qual_type(QualType::getFromOpaquePtr(tag_clang_type)); 3086 clang::Type *clang_type = tag_qual_type.getTypePtr(); 3087 if (clang_type) 3088 { 3089 TagType *tag_type = dyn_cast<TagType>(clang_type); 3090 if (tag_type) 3091 { 3092 TagDecl *tag_decl = dyn_cast<TagDecl>(tag_type->getDecl()); 3093 if (tag_decl) 3094 { 3095 tag_decl->setTagKind ((TagDecl::TagKind)kind); 3096 return true; 3097 } 3098 } 3099 } 3100 } 3101 return false; 3102} 3103 3104 3105#pragma mark DeclContext Functions 3106 3107DeclContext * 3108ClangASTContext::GetDeclContextForType (clang_type_t clang_type) 3109{ 3110 if (clang_type == NULL) 3111 return NULL; 3112 3113 QualType qual_type(QualType::getFromOpaquePtr(clang_type)); 3114 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 3115 switch (type_class) 3116 { 3117 case clang::Type::FunctionNoProto: break; 3118 case clang::Type::FunctionProto: break; 3119 case clang::Type::IncompleteArray: break; 3120 case clang::Type::VariableArray: break; 3121 case clang::Type::ConstantArray: break; 3122 case clang::Type::ExtVector: break; 3123 case clang::Type::Vector: break; 3124 case clang::Type::Builtin: break; 3125 case clang::Type::BlockPointer: break; 3126 case clang::Type::Pointer: break; 3127 case clang::Type::LValueReference: break; 3128 case clang::Type::RValueReference: break; 3129 case clang::Type::MemberPointer: break; 3130 case clang::Type::Complex: break; 3131 case clang::Type::ObjCObject: break; 3132 case clang::Type::ObjCInterface: return cast<ObjCObjectType>(qual_type.getTypePtr())->getInterface(); 3133 case clang::Type::ObjCObjectPointer: return ClangASTContext::GetDeclContextForType (cast<ObjCObjectPointerType>(qual_type.getTypePtr())->getPointeeType().getAsOpaquePtr()); 3134 case clang::Type::Record: return cast<RecordType>(qual_type)->getDecl(); 3135 case clang::Type::Enum: return cast<EnumType>(qual_type)->getDecl(); 3136 case clang::Type::Typedef: return ClangASTContext::GetDeclContextForType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr()); 3137 3138 case clang::Type::TypeOfExpr: break; 3139 case clang::Type::TypeOf: break; 3140 case clang::Type::Decltype: break; 3141 //case clang::Type::QualifiedName: break; 3142 case clang::Type::TemplateSpecialization: break; 3143 } 3144 // No DeclContext in this type... 3145 return NULL; 3146} 3147 3148#pragma mark Namespace Declarations 3149 3150NamespaceDecl * 3151ClangASTContext::GetUniqueNamespaceDeclaration (const char *name, const Declaration &decl, DeclContext *decl_ctx) 3152{ 3153 // TODO: Do something intelligent with the Declaration object passed in 3154 // like maybe filling in the SourceLocation with it... 3155 if (name) 3156 { 3157 ASTContext *ast_context = getASTContext(); 3158 if (decl_ctx == NULL) 3159 decl_ctx = ast_context->getTranslationUnitDecl(); 3160 return NamespaceDecl::Create(*ast_context, decl_ctx, SourceLocation(), &ast_context->Idents.get(name)); 3161 } 3162 return NULL; 3163} 3164 3165 3166#pragma mark Function Types 3167 3168FunctionDecl * 3169ClangASTContext::CreateFunctionDeclaration (const char *name, clang_type_t function_clang_type, int storage, bool is_inline) 3170{ 3171 if (name) 3172 { 3173 ASTContext *ast_context = getASTContext(); 3174 assert (ast_context != NULL); 3175 3176 if (name && name[0]) 3177 { 3178 return FunctionDecl::Create(*ast_context, 3179 ast_context->getTranslationUnitDecl(), 3180 SourceLocation(), 3181 DeclarationName (&ast_context->Idents.get(name)), 3182 QualType::getFromOpaquePtr(function_clang_type), 3183 NULL, 3184 (FunctionDecl::StorageClass)storage, 3185 (FunctionDecl::StorageClass)storage, 3186 is_inline); 3187 } 3188 else 3189 { 3190 return FunctionDecl::Create(*ast_context, 3191 ast_context->getTranslationUnitDecl(), 3192 SourceLocation(), 3193 DeclarationName (), 3194 QualType::getFromOpaquePtr(function_clang_type), 3195 NULL, 3196 (FunctionDecl::StorageClass)storage, 3197 (FunctionDecl::StorageClass)storage, 3198 is_inline); 3199 } 3200 } 3201 return NULL; 3202} 3203 3204clang_type_t 3205ClangASTContext::CreateFunctionType (ASTContext *ast_context, 3206 clang_type_t result_type, 3207 clang_type_t *args, 3208 unsigned num_args, 3209 bool is_variadic, 3210 unsigned type_quals) 3211{ 3212 assert (ast_context != NULL); 3213 std::vector<QualType> qual_type_args; 3214 for (unsigned i=0; i<num_args; ++i) 3215 qual_type_args.push_back (QualType::getFromOpaquePtr(args[i])); 3216 3217 // TODO: Detect calling convention in DWARF? 3218 return ast_context->getFunctionType(QualType::getFromOpaquePtr(result_type), 3219 qual_type_args.empty() ? NULL : &qual_type_args.front(), 3220 qual_type_args.size(), 3221 is_variadic, 3222 type_quals, 3223 false, // hasExceptionSpec 3224 false, // hasAnyExceptionSpec, 3225 0, // NumExs 3226 0, // const QualType *ExArray 3227 FunctionType::ExtInfo ()).getAsOpaquePtr(); // NoReturn); 3228} 3229 3230ParmVarDecl * 3231ClangASTContext::CreateParameterDeclaration (const char *name, clang_type_t param_type, int storage) 3232{ 3233 ASTContext *ast_context = getASTContext(); 3234 assert (ast_context != NULL); 3235 return ParmVarDecl::Create(*ast_context, 3236 ast_context->getTranslationUnitDecl(), 3237 SourceLocation(), 3238 name && name[0] ? &ast_context->Idents.get(name) : NULL, 3239 QualType::getFromOpaquePtr(param_type), 3240 NULL, 3241 (VarDecl::StorageClass)storage, 3242 (VarDecl::StorageClass)storage, 3243 0); 3244} 3245 3246void 3247ClangASTContext::SetFunctionParameters (FunctionDecl *function_decl, ParmVarDecl **params, unsigned num_params) 3248{ 3249 if (function_decl) 3250 function_decl->setParams (params, num_params); 3251} 3252 3253 3254#pragma mark Array Types 3255 3256clang_type_t 3257ClangASTContext::CreateArrayType (clang_type_t element_type, size_t element_count, uint32_t bit_stride) 3258{ 3259 if (element_type) 3260 { 3261 ASTContext *ast_context = getASTContext(); 3262 assert (ast_context != NULL); 3263 llvm::APInt ap_element_count (64, element_count); 3264 return ast_context->getConstantArrayType(QualType::getFromOpaquePtr(element_type), 3265 ap_element_count, 3266 ArrayType::Normal, 3267 0).getAsOpaquePtr(); // ElemQuals 3268 } 3269 return NULL; 3270} 3271 3272 3273#pragma mark TagDecl 3274 3275bool 3276ClangASTContext::StartTagDeclarationDefinition (clang_type_t clang_type) 3277{ 3278 if (clang_type) 3279 { 3280 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3281 clang::Type *t = qual_type.getTypePtr(); 3282 if (t) 3283 { 3284 TagType *tag_type = dyn_cast<TagType>(t); 3285 if (tag_type) 3286 { 3287 TagDecl *tag_decl = tag_type->getDecl(); 3288 if (tag_decl) 3289 { 3290 tag_decl->startDefinition(); 3291 return true; 3292 } 3293 } 3294 } 3295 } 3296 return false; 3297} 3298 3299bool 3300ClangASTContext::CompleteTagDeclarationDefinition (clang_type_t clang_type) 3301{ 3302 if (clang_type) 3303 { 3304 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3305 3306 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); 3307 3308 if (cxx_record_decl) 3309 { 3310 cxx_record_decl->completeDefinition(); 3311 3312 return true; 3313 } 3314 3315 ObjCObjectType *objc_class_type = dyn_cast<ObjCObjectType>(qual_type); 3316 3317 if (objc_class_type) 3318 { 3319 ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface(); 3320 3321 class_interface_decl->setForwardDecl(false); 3322 } 3323 3324 const EnumType *enum_type = dyn_cast<EnumType>(qual_type.getTypePtr()); 3325 3326 if (enum_type) 3327 { 3328 EnumDecl *enum_decl = enum_type->getDecl(); 3329 3330 if (enum_decl) 3331 { 3332 /// TODO This really needs to be fixed. 3333 3334 unsigned NumPositiveBits = 1; 3335 unsigned NumNegativeBits = 0; 3336 3337 ASTContext *ast_context = getASTContext(); 3338 3339 QualType promotion_qual_type; 3340 // If the enum integer type is less than an integer in bit width, 3341 // then we must promote it to an integer size. 3342 if (ast_context->getTypeSize(enum_decl->getIntegerType()) < ast_context->getTypeSize(ast_context->IntTy)) 3343 { 3344 if (enum_decl->getIntegerType()->isSignedIntegerType()) 3345 promotion_qual_type = ast_context->IntTy; 3346 else 3347 promotion_qual_type = ast_context->UnsignedIntTy; 3348 } 3349 else 3350 promotion_qual_type = enum_decl->getIntegerType(); 3351 3352 enum_decl->completeDefinition(enum_decl->getIntegerType(), promotion_qual_type, NumPositiveBits, NumNegativeBits); 3353 return true; 3354 } 3355 } 3356 } 3357 return false; 3358} 3359 3360 3361#pragma mark Enumeration Types 3362 3363clang_type_t 3364ClangASTContext::CreateEnumerationType (const Declaration &decl, const char *name, clang_type_t integer_qual_type) 3365{ 3366 // TODO: Do something intelligent with the Declaration object passed in 3367 // like maybe filling in the SourceLocation with it... 3368 ASTContext *ast_context = getASTContext(); 3369 assert (ast_context != NULL); 3370 3371 // TODO: ask about these... 3372// const bool IsScoped = false; 3373// const bool IsFixed = false; 3374 3375 EnumDecl *enum_decl = EnumDecl::Create (*ast_context, 3376 ast_context->getTranslationUnitDecl(), 3377 SourceLocation(), 3378 name && name[0] ? &ast_context->Idents.get(name) : NULL, 3379 SourceLocation(), 3380 NULL, false, false); //IsScoped, IsFixed); 3381 if (enum_decl) 3382 { 3383 // TODO: check if we should be setting the promotion type too? 3384 enum_decl->setIntegerType(QualType::getFromOpaquePtr (integer_qual_type)); 3385 return ast_context->getTagDeclType(enum_decl).getAsOpaquePtr(); 3386 } 3387 return NULL; 3388} 3389 3390clang_type_t 3391ClangASTContext::GetEnumerationIntegerType (clang_type_t enum_clang_type) 3392{ 3393 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type)); 3394 3395 clang::Type *clang_type = enum_qual_type.getTypePtr(); 3396 if (clang_type) 3397 { 3398 const EnumType *enum_type = dyn_cast<EnumType>(clang_type); 3399 if (enum_type) 3400 { 3401 EnumDecl *enum_decl = enum_type->getDecl(); 3402 if (enum_decl) 3403 return enum_decl->getIntegerType().getAsOpaquePtr(); 3404 } 3405 } 3406 return NULL; 3407} 3408bool 3409ClangASTContext::AddEnumerationValueToEnumerationType 3410( 3411 clang_type_t enum_clang_type, 3412 clang_type_t enumerator_clang_type, 3413 const Declaration &decl, 3414 const char *name, 3415 int64_t enum_value, 3416 uint32_t enum_value_bit_size 3417) 3418{ 3419 if (enum_clang_type && enumerator_clang_type && name) 3420 { 3421 // TODO: Do something intelligent with the Declaration object passed in 3422 // like maybe filling in the SourceLocation with it... 3423 ASTContext *ast_context = getASTContext(); 3424 IdentifierTable *identifier_table = getIdentifierTable(); 3425 3426 assert (ast_context != NULL); 3427 assert (identifier_table != NULL); 3428 QualType enum_qual_type (QualType::getFromOpaquePtr(enum_clang_type)); 3429 3430 clang::Type *clang_type = enum_qual_type.getTypePtr(); 3431 if (clang_type) 3432 { 3433 const EnumType *enum_type = dyn_cast<EnumType>(clang_type); 3434 3435 if (enum_type) 3436 { 3437 llvm::APSInt enum_llvm_apsint(enum_value_bit_size, false); 3438 enum_llvm_apsint = enum_value; 3439 EnumConstantDecl *enumerator_decl = 3440 EnumConstantDecl::Create(*ast_context, 3441 enum_type->getDecl(), 3442 SourceLocation(), 3443 name ? &identifier_table->get(name) : NULL, // Identifier 3444 QualType::getFromOpaquePtr(enumerator_clang_type), 3445 NULL, 3446 enum_llvm_apsint); 3447 3448 if (enumerator_decl) 3449 { 3450 enum_type->getDecl()->addDecl(enumerator_decl); 3451 return true; 3452 } 3453 } 3454 } 3455 } 3456 return false; 3457} 3458 3459#pragma mark Pointers & References 3460 3461clang_type_t 3462ClangASTContext::CreatePointerType (clang_type_t clang_type) 3463{ 3464 if (clang_type) 3465 { 3466 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3467 3468 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 3469 switch (type_class) 3470 { 3471 case clang::Type::ObjCObject: 3472 case clang::Type::ObjCInterface: 3473 return getASTContext()->getObjCObjectPointerType(qual_type).getAsOpaquePtr(); 3474 3475 default: 3476 return getASTContext()->getPointerType(qual_type).getAsOpaquePtr(); 3477 } 3478 } 3479 return NULL; 3480} 3481 3482clang_type_t 3483ClangASTContext::CreateLValueReferenceType (clang_type_t clang_type) 3484{ 3485 if (clang_type) 3486 return getASTContext()->getLValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr(); 3487 return NULL; 3488} 3489 3490clang_type_t 3491ClangASTContext::CreateRValueReferenceType (clang_type_t clang_type) 3492{ 3493 if (clang_type) 3494 return getASTContext()->getRValueReferenceType (QualType::getFromOpaquePtr(clang_type)).getAsOpaquePtr(); 3495 return NULL; 3496} 3497 3498clang_type_t 3499ClangASTContext::CreateMemberPointerType (clang_type_t clang_pointee_type, clang_type_t clang_class_type) 3500{ 3501 if (clang_pointee_type && clang_pointee_type) 3502 return getASTContext()->getMemberPointerType(QualType::getFromOpaquePtr(clang_pointee_type), 3503 QualType::getFromOpaquePtr(clang_class_type).getTypePtr()).getAsOpaquePtr(); 3504 return NULL; 3505} 3506 3507size_t 3508ClangASTContext::GetPointerBitSize () 3509{ 3510 ASTContext *ast_context = getASTContext(); 3511 return ast_context->getTypeSize(ast_context->VoidPtrTy); 3512} 3513 3514bool 3515ClangASTContext::IsPointerOrReferenceType (clang_type_t clang_type, clang_type_t*target_type) 3516{ 3517 if (clang_type == NULL) 3518 return false; 3519 3520 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3521 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 3522 switch (type_class) 3523 { 3524 case clang::Type::Builtin: 3525 switch (cast<clang::BuiltinType>(qual_type)->getKind()) 3526 { 3527 default: 3528 break; 3529 case clang::BuiltinType::ObjCId: 3530 case clang::BuiltinType::ObjCClass: 3531 return true; 3532 } 3533 return false; 3534 case clang::Type::ObjCObjectPointer: 3535 if (target_type) 3536 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 3537 return true; 3538 case clang::Type::BlockPointer: 3539 if (target_type) 3540 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 3541 return true; 3542 case clang::Type::Pointer: 3543 if (target_type) 3544 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 3545 return true; 3546 case clang::Type::MemberPointer: 3547 if (target_type) 3548 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 3549 return true; 3550 case clang::Type::LValueReference: 3551 if (target_type) 3552 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr(); 3553 return true; 3554 case clang::Type::RValueReference: 3555 if (target_type) 3556 *target_type = cast<LValueReferenceType>(qual_type)->desugar().getAsOpaquePtr(); 3557 return true; 3558 case clang::Type::Typedef: 3559 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr()); 3560 default: 3561 break; 3562 } 3563 return false; 3564} 3565 3566bool 3567ClangASTContext::IsIntegerType (clang_type_t clang_type, bool &is_signed) 3568{ 3569 if (!clang_type) 3570 return false; 3571 3572 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3573 const BuiltinType *builtin_type = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal()); 3574 3575 if (builtin_type) 3576 { 3577 if (builtin_type->isInteger()) 3578 is_signed = builtin_type->isSignedInteger(); 3579 3580 return true; 3581 } 3582 3583 return false; 3584} 3585 3586bool 3587ClangASTContext::IsPointerType (clang_type_t clang_type, clang_type_t*target_type) 3588{ 3589 if (clang_type) 3590 { 3591 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3592 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 3593 switch (type_class) 3594 { 3595 case clang::Type::Builtin: 3596 switch (cast<clang::BuiltinType>(qual_type)->getKind()) 3597 { 3598 default: 3599 break; 3600 case clang::BuiltinType::ObjCId: 3601 case clang::BuiltinType::ObjCClass: 3602 return true; 3603 } 3604 return false; 3605 case clang::Type::ObjCObjectPointer: 3606 if (target_type) 3607 *target_type = cast<ObjCObjectPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 3608 return true; 3609 case clang::Type::BlockPointer: 3610 if (target_type) 3611 *target_type = cast<BlockPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 3612 return true; 3613 case clang::Type::Pointer: 3614 if (target_type) 3615 *target_type = cast<PointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 3616 return true; 3617 case clang::Type::MemberPointer: 3618 if (target_type) 3619 *target_type = cast<MemberPointerType>(qual_type)->getPointeeType().getAsOpaquePtr(); 3620 return true; 3621 case clang::Type::Typedef: 3622 return ClangASTContext::IsPointerOrReferenceType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr(), target_type); 3623 default: 3624 break; 3625 } 3626 } 3627 return false; 3628} 3629 3630bool 3631ClangASTContext::IsFloatingPointType (clang_type_t clang_type, uint32_t &count, bool &is_complex) 3632{ 3633 if (clang_type) 3634 { 3635 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3636 3637 if (const BuiltinType *BT = dyn_cast<BuiltinType>(qual_type->getCanonicalTypeInternal())) 3638 { 3639 clang::BuiltinType::Kind kind = BT->getKind(); 3640 if (kind >= BuiltinType::Float && kind <= BuiltinType::LongDouble) 3641 { 3642 count = 1; 3643 is_complex = false; 3644 return true; 3645 } 3646 } 3647 else if (const ComplexType *CT = dyn_cast<ComplexType>(qual_type->getCanonicalTypeInternal())) 3648 { 3649 if (IsFloatingPointType(CT->getElementType().getAsOpaquePtr(), count, is_complex)) 3650 { 3651 count = 2; 3652 is_complex = true; 3653 return true; 3654 } 3655 } 3656 else if (const VectorType *VT = dyn_cast<VectorType>(qual_type->getCanonicalTypeInternal())) 3657 { 3658 if (IsFloatingPointType(VT->getElementType().getAsOpaquePtr(), count, is_complex)) 3659 { 3660 count = VT->getNumElements(); 3661 is_complex = false; 3662 return true; 3663 } 3664 } 3665 } 3666 return false; 3667} 3668 3669 3670bool 3671ClangASTContext::GetCXXClassName (clang_type_t clang_type, std::string &class_name) 3672{ 3673 if (clang_type) 3674 { 3675 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3676 3677 CXXRecordDecl *cxx_record_decl = qual_type->getAsCXXRecordDecl(); 3678 if (cxx_record_decl) 3679 { 3680 class_name.assign (cxx_record_decl->getIdentifier()->getNameStart()); 3681 return true; 3682 } 3683 } 3684 class_name.clear(); 3685 return false; 3686} 3687 3688 3689bool 3690ClangASTContext::IsCXXClassType (clang_type_t clang_type) 3691{ 3692 if (clang_type) 3693 { 3694 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3695 if (qual_type->getAsCXXRecordDecl() != NULL) 3696 return true; 3697 } 3698 return false; 3699} 3700 3701bool 3702ClangASTContext::IsObjCClassType (clang_type_t clang_type) 3703{ 3704 if (clang_type) 3705 { 3706 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3707 if (qual_type->isObjCObjectOrInterfaceType()) 3708 return true; 3709 } 3710 return false; 3711} 3712 3713 3714bool 3715ClangASTContext::IsCharType (clang_type_t clang_type) 3716{ 3717 if (clang_type) 3718 return QualType::getFromOpaquePtr(clang_type)->isCharType(); 3719 return false; 3720} 3721 3722bool 3723ClangASTContext::IsCStringType (clang_type_t clang_type, uint32_t &length) 3724{ 3725 clang_type_t pointee_or_element_clang_type = NULL; 3726 Flags type_flags (ClangASTContext::GetTypeInfo (clang_type, NULL, &pointee_or_element_clang_type)); 3727 3728 if (pointee_or_element_clang_type == NULL) 3729 return false; 3730 3731 if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer)) 3732 { 3733 QualType pointee_or_element_qual_type (QualType::getFromOpaquePtr (pointee_or_element_clang_type)); 3734 3735 if (pointee_or_element_qual_type.getUnqualifiedType()->isCharType()) 3736 { 3737 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3738 if (type_flags.Test (eTypeIsArray)) 3739 { 3740 // We know the size of the array and it could be a C string 3741 // since it is an array of characters 3742 length = cast<ConstantArrayType>(qual_type.getTypePtr())->getSize().getLimitedValue(); 3743 return true; 3744 } 3745 else 3746 { 3747 length = 0; 3748 return true; 3749 } 3750 3751 } 3752 } 3753 return false; 3754} 3755 3756bool 3757ClangASTContext::IsFunctionPointerType (clang_type_t clang_type) 3758{ 3759 if (clang_type) 3760 { 3761 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3762 3763 if (qual_type->isFunctionPointerType()) 3764 return true; 3765 3766 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 3767 switch (type_class) 3768 { 3769 case clang::Type::Typedef: 3770 return ClangASTContext::IsFunctionPointerType (cast<TypedefType>(qual_type)->LookThroughTypedefs().getAsOpaquePtr()); 3771 3772 case clang::Type::LValueReference: 3773 case clang::Type::RValueReference: 3774 { 3775 ReferenceType *reference_type = cast<ReferenceType>(qual_type.getTypePtr()); 3776 if (reference_type) 3777 return ClangASTContext::IsFunctionPointerType (reference_type->getPointeeType().getAsOpaquePtr()); 3778 } 3779 break; 3780 } 3781 } 3782 return false; 3783} 3784 3785size_t 3786ClangASTContext::GetArraySize (clang_type_t clang_type) 3787{ 3788 if (clang_type) 3789 { 3790 ConstantArrayType *array = cast<ConstantArrayType>(QualType::getFromOpaquePtr(clang_type).getTypePtr()); 3791 if (array) 3792 return array->getSize().getLimitedValue(); 3793 } 3794 return 0; 3795} 3796 3797bool 3798ClangASTContext::IsArrayType (clang_type_t clang_type, clang_type_t*member_type, uint64_t *size) 3799{ 3800 if (!clang_type) 3801 return false; 3802 3803 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3804 3805 const clang::Type::TypeClass type_class = qual_type->getTypeClass(); 3806 switch (type_class) 3807 { 3808 case clang::Type::ConstantArray: 3809 if (member_type) 3810 *member_type = cast<ConstantArrayType>(qual_type)->getElementType().getAsOpaquePtr(); 3811 if (size) 3812 *size = cast<ConstantArrayType>(qual_type)->getSize().getLimitedValue(ULONG_LONG_MAX); 3813 return true; 3814 case clang::Type::IncompleteArray: 3815 if (member_type) 3816 *member_type = cast<IncompleteArrayType>(qual_type)->getElementType().getAsOpaquePtr(); 3817 if (size) 3818 *size = 0; 3819 return true; 3820 case clang::Type::VariableArray: 3821 if (member_type) 3822 *member_type = cast<VariableArrayType>(qual_type)->getElementType().getAsOpaquePtr(); 3823 if (size) 3824 *size = 0; 3825 case clang::Type::DependentSizedArray: 3826 if (member_type) 3827 *member_type = cast<DependentSizedArrayType>(qual_type)->getElementType().getAsOpaquePtr(); 3828 if (size) 3829 *size = 0; 3830 return true; 3831 } 3832 return false; 3833} 3834 3835 3836#pragma mark Typedefs 3837 3838clang_type_t 3839ClangASTContext::CreateTypedefType (const char *name, clang_type_t clang_type, DeclContext *decl_ctx) 3840{ 3841 if (clang_type) 3842 { 3843 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3844 ASTContext *ast_context = getASTContext(); 3845 IdentifierTable *identifier_table = getIdentifierTable(); 3846 assert (ast_context != NULL); 3847 assert (identifier_table != NULL); 3848 if (decl_ctx == NULL) 3849 decl_ctx = ast_context->getTranslationUnitDecl(); 3850 TypedefDecl *decl = TypedefDecl::Create(*ast_context, 3851 decl_ctx, 3852 SourceLocation(), 3853 name ? &identifier_table->get(name) : NULL, // Identifier 3854 ast_context->CreateTypeSourceInfo(qual_type)); 3855 3856 // Get a uniqued QualType for the typedef decl type 3857 return ast_context->getTypedefType (decl).getAsOpaquePtr(); 3858 } 3859 return NULL; 3860} 3861 3862 3863std::string 3864ClangASTContext::GetTypeName (clang_type_t opaque_qual_type) 3865{ 3866 std::string return_name; 3867 3868 QualType qual_type(QualType::getFromOpaquePtr(opaque_qual_type)); 3869 3870 const TypedefType *typedef_type = qual_type->getAs<TypedefType>(); 3871 if (typedef_type) 3872 { 3873 const TypedefDecl *typedef_decl = typedef_type->getDecl(); 3874 return_name = typedef_decl->getQualifiedNameAsString(); 3875 } 3876 else 3877 { 3878 return_name = qual_type.getAsString(); 3879 } 3880 3881 return return_name; 3882} 3883 3884// Disable this for now since I can't seem to get a nicely formatted float 3885// out of the APFloat class without just getting the float, double or quad 3886// and then using a formatted print on it which defeats the purpose. We ideally 3887// would like to get perfect string values for any kind of float semantics 3888// so we can support remote targets. The code below also requires a patch to 3889// llvm::APInt. 3890//bool 3891//ClangASTContext::ConvertFloatValueToString (ASTContext *ast_context, clang_type_t clang_type, const uint8_t* bytes, size_t byte_size, int apint_byte_order, std::string &float_str) 3892//{ 3893// uint32_t count = 0; 3894// bool is_complex = false; 3895// if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex)) 3896// { 3897// unsigned num_bytes_per_float = byte_size / count; 3898// unsigned num_bits_per_float = num_bytes_per_float * 8; 3899// 3900// float_str.clear(); 3901// uint32_t i; 3902// for (i=0; i<count; i++) 3903// { 3904// APInt ap_int(num_bits_per_float, bytes + i * num_bytes_per_float, (APInt::ByteOrder)apint_byte_order); 3905// bool is_ieee = false; 3906// APFloat ap_float(ap_int, is_ieee); 3907// char s[1024]; 3908// unsigned int hex_digits = 0; 3909// bool upper_case = false; 3910// 3911// if (ap_float.convertToHexString(s, hex_digits, upper_case, APFloat::rmNearestTiesToEven) > 0) 3912// { 3913// if (i > 0) 3914// float_str.append(", "); 3915// float_str.append(s); 3916// if (i == 1 && is_complex) 3917// float_str.append(1, 'i'); 3918// } 3919// } 3920// return !float_str.empty(); 3921// } 3922// return false; 3923//} 3924 3925size_t 3926ClangASTContext::ConvertStringToFloatValue (ASTContext *ast_context, clang_type_t clang_type, const char *s, uint8_t *dst, size_t dst_size) 3927{ 3928 if (clang_type) 3929 { 3930 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3931 uint32_t count = 0; 3932 bool is_complex = false; 3933 if (ClangASTContext::IsFloatingPointType (clang_type, count, is_complex)) 3934 { 3935 // TODO: handle complex and vector types 3936 if (count != 1) 3937 return false; 3938 3939 StringRef s_sref(s); 3940 APFloat ap_float(ast_context->getFloatTypeSemantics(qual_type), s_sref); 3941 3942 const uint64_t bit_size = ast_context->getTypeSize (qual_type); 3943 const uint64_t byte_size = bit_size / 8; 3944 if (dst_size >= byte_size) 3945 { 3946 if (bit_size == sizeof(float)*8) 3947 { 3948 float float32 = ap_float.convertToFloat(); 3949 ::memcpy (dst, &float32, byte_size); 3950 return byte_size; 3951 } 3952 else if (bit_size >= 64) 3953 { 3954 llvm::APInt ap_int(ap_float.bitcastToAPInt()); 3955 ::memcpy (dst, ap_int.getRawData(), byte_size); 3956 return byte_size; 3957 } 3958 } 3959 } 3960 } 3961 return 0; 3962} 3963 3964unsigned 3965ClangASTContext::GetTypeQualifiers(clang_type_t clang_type) 3966{ 3967 assert (clang_type); 3968 3969 QualType qual_type (QualType::getFromOpaquePtr(clang_type)); 3970 3971 return qual_type.getQualifiers().getCVRQualifiers(); 3972} 3973