Browse Source

Fixed the native code parser to deal with namespaces.

pull/1/head
triton 13 years ago
parent
commit
0224542925
  1. 143
      src/Parser/Parser.cpp
  2. 12
      src/Parser/Parser.h

143
src/Parser/Parser.cpp

@ -49,7 +49,7 @@ static std::string GetClangResourceDir(const std::string& Dir) @@ -49,7 +49,7 @@ static std::string GetClangResourceDir(const std::string& Dir)
static std::string GetClangBuiltinIncludeDir()
{
using namespace llvm;
using namespace llvm;
SmallString<128> P( GetClangResourceDir(".") );
llvm::sys::path::append(P, "include");
@ -77,8 +77,7 @@ void Parser::Setup(ParserOptions^ Opts) @@ -77,8 +77,7 @@ void Parser::Setup(ParserOptions^ Opts)
C->createDiagnostics(ARRAY_SIZE(args), args);
CompilerInvocation* Inv = new CompilerInvocation();
CompilerInvocation::CreateFromArgs(*Inv,
args, args + ARRAY_SIZE(args), C->getDiagnostics());
CompilerInvocation::CreateFromArgs(*Inv, args, args + ARRAY_SIZE(args), C->getDiagnostics());
C->setInvocation(Inv);
TargetOptions& TO = Inv->getTargetOpts();
@ -91,8 +90,8 @@ void Parser::Setup(ParserOptions^ Opts) @@ -91,8 +90,8 @@ void Parser::Setup(ParserOptions^ Opts)
C->createFileManager();
C->createSourceManager(C->getFileManager());
if (Opts->Verbose)
C->getHeaderSearchOpts().Verbose = true;
if (Opts->Verbose)
C->getHeaderSearchOpts().Verbose = true;
// Initialize the default platform headers.
std::string ResourceDir = GetClangResourceDir(".");
@ -232,8 +231,9 @@ Cxxi::Class^ Parser::WalkRecordCXX(clang::CXXRecordDecl* Record) @@ -232,8 +231,9 @@ Cxxi::Class^ Parser::WalkRecordCXX(clang::CXXRecordDecl* Record)
if (Record->isAnonymousStructOrUnion())
return nullptr;
auto RC = gcnew Cxxi::Class();
RC->Name = marshalString<E_UTF8>(GetTagDeclName(Record));
auto NS = GetNamespace(Record);
auto RC = NS->FindClass(
marshalString<E_UTF8>(GetTagDeclName(Record)), /* Create */ true);
RC->IsPOD = Record->isPOD();
// Iterate through the record ctors.
@ -335,6 +335,116 @@ Cxxi::Field^ Parser::WalkFieldCXX(clang::FieldDecl* FD) @@ -335,6 +335,116 @@ Cxxi::Field^ Parser::WalkFieldCXX(clang::FieldDecl* FD)
//-----------------------------------//
Cxxi::Namespace^ Parser::GetNamespace(const clang::NamedDecl* ND)
{
using namespace clang;
using namespace clix;
Cxxi::Module^ M = GetModule(ND->getLocation());
// If the declaration is at global scope, just early exit.
const DeclContext *Ctx = ND->getDeclContext();
if (Ctx->isTranslationUnit())
return M;
// Else we need to do a more expensive check to get all the namespaces,
// and then perform a reverse iteration to get the namespaces in order.
typedef SmallVector<const DeclContext *, 8> ContextsTy;
ContextsTy Contexts;
for(; Ctx != nullptr; Ctx = Ctx->getParent())
Contexts.push_back(Ctx);
assert(Contexts.back()->isTranslationUnit());
Contexts.pop_back();
Cxxi::Namespace^ NS = M;
for (auto I = Contexts.rbegin(), E = Contexts.rend(); I != E; ++I)
{
const DeclContext* Ctx = *I;
switch(Ctx->getDeclKind())
{
case Decl::Namespace:
{
const NamespaceDecl* ND = cast<NamespaceDecl>(Ctx);
if (ND->isAnonymousNamespace())
continue;
NS = NS->FindNamespace(marshalString<E_UTF8>(ND->getName()));
break;
}
case Decl::LinkageSpec:
{
const LinkageSpecDecl* LD = cast<LinkageSpecDecl>(Ctx);
continue;
}
case Decl::CXXRecord:
{
// FIXME: Ignore record namespaces...
// We might be able to translate these to C# nested types.
continue;
}
default:
{
StringRef Kind = Ctx->getDeclKindName();
printf("Unhandled declaration context kind: %s\n", Kind);
assert(0 && "Unhandled declaration context kind");
} }
}
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)
{
using namespace Cxxi;
@ -451,7 +561,13 @@ Cxxi::Type^ Parser::ConvertTypeToCLR(clang::QualType QualType) @@ -451,7 +561,13 @@ Cxxi::Type^ Parser::ConvertTypeToCLR(clang::QualType QualType)
// Assume that the type has already been defined for now.
String Name(GetTagDeclName(RD));
auto D = Lib->FindClass(marshalString<E_UTF8>(Name));
// We have to try to find the class type. If there is none yet,
// then create it, this is needed to deal properly with forward
// referenced types.
auto NS = GetNamespace(RD);
auto D = NS->FindClass(marshalString<E_UTF8>(Name), true /* Create */);
auto TT = gcnew Cxxi::TagType();
TT->Declaration = D;
@ -766,8 +882,11 @@ void Parser::WalkDeclaration(clang::Decl* D) @@ -766,8 +882,11 @@ void Parser::WalkDeclaration(clang::Decl* D)
auto Class = WalkRecordCXX(RD);
HandleComments(RD, Class);
auto M = GetModule(RD->getLocation());
M->Global->Classes->Add(Class);
auto NS = GetNamespace(RD);
auto RC = NS->FindClass(marshalString<E_UTF8>(GetTagDeclName(RD)), /* Create */ false);
if (!RC)
NS->Classes->Add(Class);
break;
}
@ -781,7 +900,7 @@ void Parser::WalkDeclaration(clang::Decl* D) @@ -781,7 +900,7 @@ void Parser::WalkDeclaration(clang::Decl* D)
HandleComments(ED, E);
auto M = GetModule(ED->getLocation());
M->Global->Enums->Add(E);
M->Enums->Add(E);
break;
}
@ -795,7 +914,7 @@ void Parser::WalkDeclaration(clang::Decl* D) @@ -795,7 +914,7 @@ void Parser::WalkDeclaration(clang::Decl* D)
HandleComments(FD, F);
auto M = GetModule(FD->getLocation());
M->Global->Functions->Add(F);
M->Functions->Add(F);
break;
}

12
src/Parser/Parser.h

@ -32,12 +32,12 @@ @@ -32,12 +32,12 @@
public ref struct ParserOptions
{
// C/C++ header file name.
System::String^ FileName;
// C/C++ header file name.
System::String^ FileName;
Cxxi::Library^ Library;
Cxxi::Library^ Library;
bool Verbose;
bool Verbose;
};
struct Parser
@ -63,9 +63,11 @@ protected: @@ -63,9 +63,11 @@ protected:
bool IsValidDeclaration(const clang::SourceLocation& Loc);
std::string GetDeclMangledName(clang::Decl*, clang::TargetCXXABI);
std::string GetTypeBindName(const clang::Type*);
void HandleComments(clang::Decl* D, Cxxi::Declaration^);
Cxxi::Module^ GetModule(clang::SourceLocation Loc);
Cxxi::Namespace^ GetNamespace(const clang::NamedDecl*);
Cxxi::Type^ ConvertTypeToCLR(clang::QualType QualType);
void HandleComments(clang::Decl* D, Cxxi::Declaration^);
gcroot<Cxxi::Library^> Lib;
llvm::OwningPtr<clang::CompilerInstance> C;

Loading…
Cancel
Save