Browse Source

Added support for typedefs to the native parser. Added support for user-specified include directories.

pull/1/head
triton 13 years ago
parent
commit
4c4e65723c
  1. 224
      src/Parser/Parser.cpp
  2. 22
      src/Parser/Parser.h

224
src/Parser/Parser.cpp

@ -1,23 +1,23 @@
/************************************************************************ /************************************************************************
* *
* Flush3D <http://www.flush3d.com> © (2008-201x) * Cxxi
* Licensed under the LGPL 2.1 (GNU Lesser General Public License) * Licensed under the simplified BSD license. All rights reserved.
* *
************************************************************************/ ************************************************************************/
#include "Parser.h" #include "Parser.h"
#include "Interop.h"
#include <llvm/Support/Path.h> #include <llvm/Support/Path.h>
#include <clang/Basic/Version.h> #include <clang/Basic/Version.h>
#include <clang/Config/config.h> #include <clang/Config/config.h>
#include "clang/AST/ASTContext.h" #include <clang/AST/ASTContext.h>
#include "clang/Lex/HeaderSearch.h" #include <clang/Lex/HeaderSearch.h>
#include <clang/Lex/PreprocessingRecord.h> #include <clang/Lex/PreprocessingRecord.h>
#include "clang/Frontend/HeaderSearchOptions.h" #include <clang/Frontend/HeaderSearchOptions.h>
#include <clang/Frontend/Utils.h> #include <clang/Frontend/Utils.h>
#include <clang/Driver/Util.h> #include <clang/Driver/Util.h>
#include "Interop.h"
#include <string> #include <string>
//-----------------------------------// //-----------------------------------//
@ -62,6 +62,7 @@ static std::string GetClangBuiltinIncludeDir()
void Parser::Setup(ParserOptions^ Opts) void Parser::Setup(ParserOptions^ Opts)
{ {
using namespace clang; using namespace clang;
using namespace clix;
const char* args[] = const char* args[] =
{ {
@ -93,6 +94,12 @@ void Parser::Setup(ParserOptions^ Opts)
if (Opts->Verbose) if (Opts->Verbose)
C->getHeaderSearchOpts().Verbose = true; C->getHeaderSearchOpts().Verbose = true;
for each(System::String^% include in Opts->IncludeDirs)
{
String s = marshalString<E_UTF8>(include);
C->getHeaderSearchOpts().AddPath(s, frontend::Quoted, true, false, true);
}
// Initialize the default platform headers. // Initialize the default platform headers.
std::string ResourceDir = GetClangResourceDir("."); std::string ResourceDir = GetClangResourceDir(".");
C->getHeaderSearchOpts().ResourceDir = ResourceDir; C->getHeaderSearchOpts().ResourceDir = ResourceDir;
@ -180,25 +187,27 @@ std::string Parser::GetDeclMangledName(clang::Decl* D, clang::TargetCXXABI ABI)
//-----------------------------------// //-----------------------------------//
static std::string GetDeclName(const clang::NamedDecl* D)
{
if (const clang::IdentifierInfo *II = D->getIdentifier())
return II->getName();
return D->getNameAsString();
}
static std::string GetTagDeclName(const clang::TagDecl* D) static std::string GetTagDeclName(const clang::TagDecl* D)
{ {
using namespace clang; using namespace clang;
if (const IdentifierInfo *II = D->getIdentifier()) if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl())
return II->getName();
else if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl())
{ {
assert(Typedef->getIdentifier() && "Typedef without identifier?"); assert(Typedef->getIdentifier() && "Typedef without identifier?");
return Typedef->getIdentifier()->getName(); return GetDeclName(Typedef);
} }
else
return D->getNameAsString();
assert(0 && "Expected to have a name"); return GetDeclName(D);
return std::string();
} }
std::string Parser::GetTypeBindName(const clang::Type* Type) std::string Parser::GetTypeName(const clang::Type* Type)
{ {
using namespace clang; using namespace clang;
@ -213,12 +222,11 @@ std::string Parser::GetTypeBindName(const clang::Type* Type)
PrintingPolicy pp(C->getLangOpts()); PrintingPolicy pp(C->getLangOpts());
pp.SuppressTagKeyword = true; pp.SuppressTagKeyword = true;
//pp.SuppressSpecifiers = true;
std::string TypeName; std::string TypeName;
QualType::getAsStringInternal(Type, Qualifiers(), TypeName, pp); QualType::getAsStringInternal(Type, Qualifiers(), TypeName, pp);
return std::string(); return TypeName;
} }
//-----------------------------------// //-----------------------------------//
@ -229,12 +237,25 @@ Cxxi::Class^ Parser::WalkRecordCXX(clang::CXXRecordDecl* Record)
using namespace clix; using namespace clix;
if (Record->isAnonymousStructOrUnion()) if (Record->isAnonymousStructOrUnion())
{
assert(0);
return nullptr; return nullptr;
}
if (Record->hasFlexibleArrayMember())
{
assert(0);
return nullptr;
}
auto NS = GetNamespace(Record); auto NS = GetNamespace(Record);
auto RC = NS->FindClass( auto RC = NS->FindClass(
marshalString<E_UTF8>(GetTagDeclName(Record)), /* Create */ true); marshalString<E_UTF8>(GetTagDeclName(Record)), /* Create */ true);
RC->IsPOD = Record->isPOD(); RC->IsPOD = Record->isPOD();
RC->IsUnion = Record->isUnion();
// Get the record layout information.
const ASTRecordLayout& Layout = C->getASTContext().getASTRecordLayout(Record);
// Iterate through the record ctors. // Iterate through the record ctors.
for(auto it = Record->ctor_begin(); it != Record->ctor_end(); ++it) for(auto it = Record->ctor_begin(); it != Record->ctor_end(); ++it)
@ -260,12 +281,13 @@ Cxxi::Class^ Parser::WalkRecordCXX(clang::CXXRecordDecl* Record)
for(auto it = Record->field_begin(); it != Record->field_end(); ++it) for(auto it = Record->field_begin(); it != Record->field_end(); ++it)
{ {
FieldDecl* FD = (*it); FieldDecl* FD = (*it);
Cxxi::Field^ Field = WalkFieldCXX(FD); Cxxi::Field^ Field = WalkFieldCXX(FD);
Field->Offset = Layout.getFieldOffset(FD->getFieldIndex());
RC->Fields->Add(Field); RC->Fields->Add(Field);
} }
// Get the record layout information.
const ASTRecordLayout& Layout = C->getASTContext().getASTRecordLayout(Record);
//Debug("Size: %I64d\n", Layout.getSize().getQuantity()); //Debug("Size: %I64d\n", Layout.getSize().getQuantity());
return RC; return RC;
@ -289,10 +311,6 @@ Cxxi::Method^ Parser::WalkMethodCXX(clang::CXXMethodDecl* Method)
ParmVarDecl* Parm = (*it); ParmVarDecl* Parm = (*it);
QualType ParmType = Parm->getType(); QualType ParmType = Parm->getType();
std::string ParmTypeName = GetTypeBindName(ParmType.getTypePtr());
Debug("\tParameter: %s %s\n",
ParmTypeName.c_str(), Parm->getName().str().c_str());
} }
std::string Mangled = GetDeclMangledName(Method, CXXABI_Microsoft); std::string Mangled = GetDeclMangledName(Method, CXXABI_Microsoft);
@ -325,7 +343,7 @@ Cxxi::Field^ Parser::WalkFieldCXX(clang::FieldDecl* FD)
Cxxi::Field^ F = gcnew Cxxi::Field(); Cxxi::Field^ F = gcnew Cxxi::Field();
F->Name = marshalString<E_UTF8>(FD->getName()); F->Name = marshalString<E_UTF8>(FD->getName());
F->Type = ConvertTypeToCLR(FD->getType()); F->Type = WalkType(FD->getType());
F->Access = ConvertToAccess(FD->getAccess()); F->Access = ConvertToAccess(FD->getAccess());
HandleComments(FD, F); HandleComments(FD, F);
@ -394,58 +412,9 @@ Cxxi::Namespace^ Parser::GetNamespace(const clang::NamedDecl* ND)
} }
return NS; return NS;
#if 0
if (const ClassTemplateSpecializationDecl *Spec
= dyn_cast<ClassTemplateSpecializationDecl>(*I)) {
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
std::string TemplateArgsStr
= TemplateSpecializationType::PrintTemplateArgumentList(
TemplateArgs.data(),
TemplateArgs.size(),
P);
OS << Spec->getName() << TemplateArgsStr;
} else if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(*I)) {
if (ND->isAnonymousNamespace())
OS << "<anonymous namespace>";
else
OS << *ND;
} else if (const RecordDecl *RD = dyn_cast<RecordDecl>(*I)) {
if (!RD->getIdentifier())
OS << "<anonymous " << RD->getKindName() << '>';
else
OS << *RD;
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
const FunctionProtoType *FT = 0;
if (FD->hasWrittenPrototype())
FT = dyn_cast<FunctionProtoType>(FD->getType()->castAs<FunctionType>());
OS << *FD << '(';
if (FT) {
unsigned NumParams = FD->getNumParams();
for (unsigned i = 0; i < NumParams; ++i) {
if (i)
OS << ", ";
OS << FD->getParamDecl(i)->getType().stream(P);
}
if (FT->isVariadic()) {
if (NumParams > 0)
OS << ", ";
OS << "...";
}
}
OS << ')';
} else {
OS << *cast<NamedDecl>(*I);
}
OS << "::";
}
#endif
} }
static Cxxi::PrimitiveType ConvertBuiltinTypeToCLR(const clang::BuiltinType* Builtin) static Cxxi::PrimitiveType WalkBuiltinType(const clang::BuiltinType* Builtin)
{ {
using namespace Cxxi; using namespace Cxxi;
@ -490,7 +459,7 @@ static Cxxi::PrimitiveType ConvertBuiltinTypeToCLR(const clang::BuiltinType* Bui
//-----------------------------------// //-----------------------------------//
Cxxi::Type^ Parser::ConvertTypeToCLR(clang::QualType QualType) Cxxi::Type^ Parser::WalkType(clang::QualType QualType)
{ {
using namespace clang; using namespace clang;
using namespace clix; using namespace clix;
@ -514,7 +483,7 @@ Cxxi::Type^ Parser::ConvertTypeToCLR(clang::QualType QualType)
assert(Builtin && "Expected a builtin type"); assert(Builtin && "Expected a builtin type");
auto BT = gcnew Cxxi::BuiltinType(); auto BT = gcnew Cxxi::BuiltinType();
BT->Type = ConvertBuiltinTypeToCLR(Builtin); BT->Type = WalkBuiltinType(Builtin);
return BT; return BT;
} }
@ -538,21 +507,35 @@ Cxxi::Type^ Parser::ConvertTypeToCLR(clang::QualType QualType)
auto P = gcnew Cxxi::PointerType(); auto P = gcnew Cxxi::PointerType();
P->Modifier = Cxxi::PointerType::TypeModifier::Pointer; P->Modifier = Cxxi::PointerType::TypeModifier::Pointer;
P->Pointee = ConvertTypeToCLR(Pointer->getPointeeType()); P->Pointee = WalkType(Pointer->getPointeeType());
return P; return P;
} }
case Type::Typedef: case Type::Typedef:
{ {
auto TT = Type->getAs<clang::TypedefType>(); auto TT = Type->getAs<clang::TypedefType>();
const TypedefNameDecl* TND = TT->getDecl(); TypedefNameDecl* TD = TT->getDecl();
return ConvertTypeToCLR(TND->getUnderlyingType()); auto NS = GetNamespace(TD);
auto TDD = NS->FindTypedef(marshalString<E_UTF8>(GetDeclName(TD)));
// If we did not find an existing typedef declaration, this is a type
// used by the standard library, so we walk the decl to process it.
if (!TDD)
{
TDD = (Cxxi::Typedef^) WalkDeclaration(TD, false);
assert(TDD != nullptr);
}
auto Type = gcnew Cxxi::TypedefType();
Type->Declaration = TDD;
return Type;
} }
case Type::Elaborated: case Type::Elaborated:
{ {
auto ET = Type->getAs<clang::ElaboratedType>(); auto ET = Type->getAs<clang::ElaboratedType>();
return ConvertTypeToCLR(ET->getNamedType()); return WalkType(ET->getNamedType());
} }
case Type::Record: case Type::Record:
{ {
@ -577,14 +560,14 @@ Cxxi::Type^ Parser::ConvertTypeToCLR(clang::QualType QualType)
case Type::Paren: case Type::Paren:
{ {
auto PT = Type->getAs<clang::ParenType>(); auto PT = Type->getAs<clang::ParenType>();
return ConvertTypeToCLR(PT->getInnerType()); return WalkType(PT->getInnerType());
} }
case Type::ConstantArray: case Type::ConstantArray:
{ {
auto AT = AST->getAsConstantArrayType(QualType); auto AT = AST->getAsConstantArrayType(QualType);
auto A = gcnew Cxxi::ArrayType(); auto A = gcnew Cxxi::ArrayType();
A->Type = ConvertTypeToCLR(AT->getElementType()); A->Type = WalkType(AT->getElementType());
A->SizeType = Cxxi::ArrayType::ArraySize::Constant; A->SizeType = Cxxi::ArrayType::ArraySize::Constant;
A->Size = AST->getConstantArrayElementCount(AT); A->Size = AST->getConstantArrayElementCount(AT);
@ -595,19 +578,22 @@ Cxxi::Type^ Parser::ConvertTypeToCLR(clang::QualType QualType)
auto FP = Type->getAs<clang::FunctionProtoType>(); auto FP = Type->getAs<clang::FunctionProtoType>();
auto F = gcnew Cxxi::FunctionType(); auto F = gcnew Cxxi::FunctionType();
F->ReturnType = ConvertTypeToCLR(FP->getResultType()); F->ReturnType = WalkType(FP->getResultType());
for (unsigned i = 0; i < FP->getNumArgs(); ++i)
F->Arguments->Add(WalkType(FP->getArgType(i)));
return F; return F;
} }
case Type::TypeOf: case Type::TypeOf:
{ {
auto TO = Type->getAs<clang::TypeOfType>(); auto TO = Type->getAs<clang::TypeOfType>();
return ConvertTypeToCLR(TO->getUnderlyingType()); return WalkType(TO->getUnderlyingType());
} }
case Type::TypeOfExpr: case Type::TypeOfExpr:
{ {
auto TO = Type->getAs<clang::TypeOfExprType>(); auto TO = Type->getAs<clang::TypeOfExprType>();
return ConvertTypeToCLR(TO->getUnderlyingExpr()->getType()); return WalkType(TO->getUnderlyingExpr()->getType());
} }
default: default:
{ {
@ -631,7 +617,7 @@ Cxxi::Enumeration^ Parser::WalkEnum(clang::EnumDecl* ED)
// Get the underlying integer backing the enum. // Get the underlying integer backing the enum.
QualType IntType = ED->getIntegerType(); QualType IntType = ED->getIntegerType();
E->Type = safe_cast<Cxxi::BuiltinType^>(ConvertTypeToCLR(IntType)); E->Type = safe_cast<Cxxi::BuiltinType^>(WalkType(IntType));
for(auto it = ED->enumerator_begin(); it != ED->enumerator_end(); ++it) for(auto it = ED->enumerator_begin(); it != ED->enumerator_end(); ++it)
{ {
@ -665,7 +651,7 @@ Cxxi::Function^ Parser::WalkFunction(clang::FunctionDecl* FD)
F->IsVariadic = FD->isVariadic(); F->IsVariadic = FD->isVariadic();
F->IsInline = FD->isInlined(); F->IsInline = FD->isInlined();
F->CallingConvention = Cxxi::CallingConvention::Default; F->CallingConvention = Cxxi::CallingConvention::Default;
F->ReturnType = ConvertTypeToCLR(FD->getResultType()); F->ReturnType = WalkType(FD->getResultType());
for(auto it = FD->param_begin(); it != FD->param_end(); ++it) for(auto it = FD->param_begin(); it != FD->param_end(); ++it)
{ {
@ -673,7 +659,7 @@ Cxxi::Function^ Parser::WalkFunction(clang::FunctionDecl* FD)
auto P = gcnew Cxxi::Parameter(); auto P = gcnew Cxxi::Parameter();
P->Name = marshalString<E_UTF8>(VD->getNameAsString()); P->Name = marshalString<E_UTF8>(VD->getNameAsString());
P->Type = ConvertTypeToCLR(VD->getType()); P->Type = WalkType(VD->getType());
P->HasDefaultValue = VD->hasDefaultArg(); P->HasDefaultValue = VD->hasDefaultArg();
F->Parameters->Add(P); F->Parameters->Add(P);
@ -742,6 +728,12 @@ Cxxi::Module^ Parser::GetModule(clang::SourceLocation Loc)
SourceManager& SM = C->getSourceManager(); SourceManager& SM = C->getSourceManager();
StringRef File = SM.getFilename(Loc); StringRef File = SM.getFilename(Loc);
if (!File.data() || File.empty())
{
assert(0 && "Expected to find a valid file");
return nullptr;
}
return Lib->FindOrCreateModule(marshalString<E_UTF8>(File)); return Lib->FindOrCreateModule(marshalString<E_UTF8>(File));
} }
@ -837,12 +829,15 @@ void Parser::HandleComments(clang::Decl* D, Cxxi::Declaration^ Decl)
//-----------------------------------// //-----------------------------------//
void Parser::WalkDeclaration(clang::Decl* D) Cxxi::Declaration^ Parser::WalkDeclaration(clang::Decl* D, bool ignoreSystemDecls)
{ {
using namespace clang; using namespace clang;
using namespace clix;
if (!IsValidDeclaration(D->getLocation())) // Ignore declarations that do not come from user-provided
return; // header files.
if (ignoreSystemDecls && !IsValidDeclaration(D->getLocation()))
return nullptr;
if(NamedDecl* ND = dyn_cast<NamedDecl>(D)) if(NamedDecl* ND = dyn_cast<NamedDecl>(D))
{ {
@ -869,7 +864,7 @@ void Parser::WalkDeclaration(clang::Decl* D)
StringRef AnnotationText = Annotation->getAnnotation(); StringRef AnnotationText = Annotation->getAnnotation();
} }
using namespace clix; Cxxi::Declaration^ Decl;
switch(D->getKind()) switch(D->getKind())
{ {
@ -888,6 +883,8 @@ void Parser::WalkDeclaration(clang::Decl* D)
if (!RC) if (!RC)
NS->Classes->Add(Class); NS->Classes->Add(Class);
Decl = Class;
break; break;
} }
case Decl::Enum: case Decl::Enum:
@ -899,8 +896,10 @@ void Parser::WalkDeclaration(clang::Decl* D)
auto E = WalkEnum(ED); auto E = WalkEnum(ED);
HandleComments(ED, E); HandleComments(ED, E);
auto M = GetModule(ED->getLocation()); auto NS = GetNamespace(ED);
M->Enums->Add(E); NS->Enums->Add(E);
Decl = E;
break; break;
} }
@ -913,8 +912,10 @@ void Parser::WalkDeclaration(clang::Decl* D)
auto F = WalkFunction(FD); auto F = WalkFunction(FD);
HandleComments(FD, F); HandleComments(FD, F);
auto M = GetModule(FD->getLocation()); auto NS = GetNamespace(FD);
M->Functions->Add(F); NS->Functions->Add(F);
Decl = F;
break; break;
} }
@ -924,8 +925,8 @@ void Parser::WalkDeclaration(clang::Decl* D)
for (auto it = LS->decls_begin(); it != LS->decls_end(); ++it) for (auto it = LS->decls_begin(); it != LS->decls_end(); ++it)
{ {
Decl* D = (*it); clang::Decl* D = (*it);
WalkDeclaration(D); Decl = WalkDeclaration(D);
} }
break; break;
@ -933,21 +934,17 @@ void Parser::WalkDeclaration(clang::Decl* D)
case Decl::Typedef: case Decl::Typedef:
{ {
TypedefDecl* TD = cast<TypedefDecl>(D); TypedefDecl* TD = cast<TypedefDecl>(D);
const QualType& Type = TD->getUnderlyingType(); const QualType& Type = TD->getUnderlyingType();
std::string Name = GetTypeBindName(Type.getTypePtr());
if (Type->isBuiltinType())
break;
#if 0 auto Typedef = gcnew Cxxi::Typedef();
// If we have a type name for a previously unnamed type, Typedef->Name = marshalString<E_UTF8>(GetDeclName(TD));
// then use this name as the name of the original type. Typedef->Type = WalkType(Type);
if(auto CType = ConvertTypeToCLR(Type)) auto NS = GetNamespace(TD);
CType->Name = marshalString<E_UTF8>(Name); NS->Typedefs->Add(Typedef);
#endif
Decl = Typedef;
break; break;
} }
case Decl::Namespace: case Decl::Namespace:
@ -956,8 +953,8 @@ void Parser::WalkDeclaration(clang::Decl* D)
for (auto it = ND->decls_begin(); it != ND->decls_end(); ++it) for (auto it = ND->decls_begin(); it != ND->decls_end(); ++it)
{ {
Decl* D = (*it); clang::Decl* D = (*it);
WalkDeclaration(D); Decl = WalkDeclaration(D);
} }
break; break;
@ -968,6 +965,8 @@ void Parser::WalkDeclaration(clang::Decl* D)
//assert(0 && "Unhandled declaration kind"); //assert(0 && "Unhandled declaration kind");
break; break;
} }; } };
return Decl;
} }
//-----------------------------------// //-----------------------------------//
@ -990,8 +989,7 @@ bool Parser::Parse(const std::string& File)
if (!file) if (!file)
{ {
Debug("Filename '%s' was not found." Debug("Filename '%s' was not found.\n", File.c_str());
"Check your compiler paths.\n", File.c_str());
return false; return false;
} }

22
src/Parser/Parser.h

@ -1,7 +1,7 @@
/************************************************************************ /************************************************************************
* *
* Flush3D <http://www.flush3d.com> © (2008-201x) * Cxxi
* Licensed under the LGPL 2.1 (GNU Lesser General Public License) * Licensed under the simplified BSD license. All rights reserved.
* *
************************************************************************/ ************************************************************************/
@ -30,8 +30,18 @@
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
#define Debug printf #define Debug printf
using namespace System::Collections::Generic;
public ref struct ParserOptions public ref struct ParserOptions
{ {
ParserOptions()
{
IncludeDirs = gcnew List<System::String^>();
}
// Include directories
List<System::String^>^ IncludeDirs;
// C/C++ header file name. // C/C++ header file name.
System::String^ FileName; System::String^ FileName;
@ -51,23 +61,25 @@ protected:
// AST traversers // AST traversers
void WalkAST(); void WalkAST();
void WalkDeclaration(clang::Decl* D);
void WalkMacros(clang::PreprocessingRecord* PR); void WalkMacros(clang::PreprocessingRecord* PR);
Cxxi::Declaration^ WalkDeclaration(clang::Decl* D,
bool IgnoreSystemDecls = true);
Cxxi::Enumeration^ WalkEnum(clang::EnumDecl*); Cxxi::Enumeration^ WalkEnum(clang::EnumDecl*);
Cxxi::Function^ WalkFunction(clang::FunctionDecl*); Cxxi::Function^ WalkFunction(clang::FunctionDecl*);
Cxxi::Class^ WalkRecordCXX(clang::CXXRecordDecl*); Cxxi::Class^ WalkRecordCXX(clang::CXXRecordDecl*);
Cxxi::Method^ WalkMethodCXX(clang::CXXMethodDecl*); Cxxi::Method^ WalkMethodCXX(clang::CXXMethodDecl*);
Cxxi::Field^ WalkFieldCXX(clang::FieldDecl*); Cxxi::Field^ WalkFieldCXX(clang::FieldDecl*);
Cxxi::Type^ WalkType(clang::QualType QualType);
// Clang helpers // Clang helpers
bool IsValidDeclaration(const clang::SourceLocation& Loc); bool IsValidDeclaration(const clang::SourceLocation& Loc);
std::string GetDeclMangledName(clang::Decl*, clang::TargetCXXABI); std::string GetDeclMangledName(clang::Decl*, clang::TargetCXXABI);
std::string GetTypeBindName(const clang::Type*); std::string GetTypeName(const clang::Type*);
void HandleComments(clang::Decl* D, Cxxi::Declaration^); void HandleComments(clang::Decl* D, Cxxi::Declaration^);
Cxxi::Module^ GetModule(clang::SourceLocation Loc); Cxxi::Module^ GetModule(clang::SourceLocation Loc);
Cxxi::Namespace^ GetNamespace(const clang::NamedDecl*); Cxxi::Namespace^ GetNamespace(const clang::NamedDecl*);
Cxxi::Type^ ConvertTypeToCLR(clang::QualType QualType);
gcroot<Cxxi::Library^> Lib; gcroot<Cxxi::Library^> Lib;
llvm::OwningPtr<clang::CompilerInstance> C; llvm::OwningPtr<clang::CompilerInstance> C;

Loading…
Cancel
Save