Browse Source

Completely re-work the way we handle namespaces/declaration contexts in the native parser to properly handle nested definitions.

pull/1/head
triton 12 years ago
parent
commit
5e475658a8
  1. 133
      src/Parser/Parser.cpp
  2. 8
      src/Parser/Parser.h

133
src/Parser/Parser.cpp

@ -606,28 +606,72 @@ CppSharp::Field^ Parser::WalkFieldCXX(clang::FieldDecl* FD, CppSharp::Class^ Cla
//-----------------------------------// //-----------------------------------//
CppSharp::Namespace^ Parser::GetNamespace(const clang::NamedDecl* ND) CppSharp::TranslationUnit^ Parser::GetTranslationUnit(clang::SourceLocation Loc,
SourceLocationKind *Kind)
{ {
using namespace clang; using namespace clang;
using namespace clix;
SourceLocation Loc = ND->getLocation(); SourceManager& SM = C->getSourceManager();
if (Loc.isMacroID())
Loc = SM.getExpansionLoc(Loc);
StringRef File;
auto LocKind = GetLocationKind(Loc);
switch(LocKind)
{
case SourceLocationKind::Invalid:
File = "<invalid>";
break;
case SourceLocationKind::Builtin:
File = "<built-in>";
break;
case SourceLocationKind::CommandLine:
File = "<command-line>";
break;
default:
File = SM.getFilename(Loc);
assert(!File.empty() && "Expected to find a valid file");
break;
}
if (Kind)
*Kind = LocKind;
auto Unit = Lib->FindOrCreateModule(clix::marshalString<clix::E_UTF8>(File));
if (LocKind != SourceLocationKind::Invalid)
Unit->IsSystemHeader = SM.isInSystemHeader(Loc);
return Unit;
}
//-----------------------------------//
CppSharp::TranslationUnit^ Parser::GetTranslationUnit(const clang::Decl* D)
{
clang::SourceLocation Loc = D->getLocation();
SourceLocationKind Kind; SourceLocationKind Kind;
CppSharp::TranslationUnit^ M = GetModule(Loc, &Kind); CppSharp::TranslationUnit^ Unit = GetTranslationUnit(Loc, &Kind);
if (Kind == SourceLocationKind::Builtin || return Unit;
Kind == SourceLocationKind::CommandLine) }
return M;
CppSharp::DeclarationContext^ Parser::GetNamespace(clang::Decl* D,
clang::DeclContext *Ctx)
{
using namespace clang;
// If the declaration is at global scope, just early exit. // If the declaration is at global scope, just early exit.
const DeclContext *Ctx = ND->getDeclContext();
if (Ctx->isTranslationUnit()) if (Ctx->isTranslationUnit())
return M; return GetTranslationUnit(D);
CppSharp::TranslationUnit^ Unit = GetTranslationUnit(cast<Decl>(Ctx));
// Else we need to do a more expensive check to get all the namespaces, // 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. // and then perform a reverse iteration to get the namespaces in order.
typedef SmallVector<const DeclContext *, 8> ContextsTy; typedef SmallVector<DeclContext *, 8> ContextsTy;
ContextsTy Contexts; ContextsTy Contexts;
for(; Ctx != nullptr; Ctx = Ctx->getParent()) for(; Ctx != nullptr; Ctx = Ctx->getParent())
@ -636,12 +680,12 @@ CppSharp::Namespace^ Parser::GetNamespace(const clang::NamedDecl* ND)
assert(Contexts.back()->isTranslationUnit()); assert(Contexts.back()->isTranslationUnit());
Contexts.pop_back(); Contexts.pop_back();
CppSharp::Namespace^ NS = M; CppSharp::DeclarationContext^ DC = Unit;
for (auto I = Contexts.rbegin(), E = Contexts.rend(); I != E; ++I) for (auto I = Contexts.rbegin(), E = Contexts.rend(); I != E; ++I)
{ {
const DeclContext* Ctx = *I; DeclContext* Ctx = *I;
switch(Ctx->getDeclKind()) switch(Ctx->getDeclKind())
{ {
case Decl::Namespace: case Decl::Namespace:
@ -649,9 +693,9 @@ CppSharp::Namespace^ Parser::GetNamespace(const clang::NamedDecl* ND)
const NamespaceDecl* ND = cast<NamespaceDecl>(Ctx); const NamespaceDecl* ND = cast<NamespaceDecl>(Ctx);
if (ND->isAnonymousNamespace()) if (ND->isAnonymousNamespace())
continue; continue;
auto Name = marshalString<E_UTF8>(ND->getName()); auto Name = clix::marshalString<clix::E_UTF8>(ND->getName());
NS = NS->FindCreateNamespace(Name, NS); DC = DC->FindCreateNamespace(Name);
break; continue;
} }
case Decl::LinkageSpec: case Decl::LinkageSpec:
{ {
@ -660,8 +704,8 @@ CppSharp::Namespace^ Parser::GetNamespace(const clang::NamedDecl* ND)
} }
case Decl::CXXRecord: case Decl::CXXRecord:
{ {
// FIXME: Ignore record namespaces... auto RD = cast<CXXRecordDecl>(Ctx);
// We might be able to translate these to C# nested types. DC = WalkRecordCXX(RD);
continue; continue;
} }
case Decl::ClassTemplateSpecialization: case Decl::ClassTemplateSpecialization:
@ -678,7 +722,12 @@ CppSharp::Namespace^ Parser::GetNamespace(const clang::NamedDecl* ND)
} } } }
} }
return NS; return DC;
}
CppSharp::DeclarationContext^ Parser::GetNamespace(clang::Decl *D)
{
return GetNamespace(D, D->getDeclContext());
} }
static CppSharp::PrimitiveType WalkBuiltinType(const clang::BuiltinType* Builtin) static CppSharp::PrimitiveType WalkBuiltinType(const clang::BuiltinType* Builtin)
@ -1327,50 +1376,6 @@ void Parser::WalkAST()
//-----------------------------------// //-----------------------------------//
CppSharp::TranslationUnit^ Parser::GetModule(clang::SourceLocation Loc,
SourceLocationKind *Kind)
{
using namespace clang;
using namespace clix;
SourceManager& SM = C->getSourceManager();
if (Loc.isMacroID())
Loc = SM.getExpansionLoc(Loc);
StringRef File;
auto LocKind = GetLocationKind(Loc);
switch(LocKind)
{
case SourceLocationKind::Invalid:
File = "<invalid>";
break;
case SourceLocationKind::Builtin:
File = "<built-in>";
break;
case SourceLocationKind::CommandLine:
File = "<command-line>";
break;
default:
File = SM.getFilename(Loc);
assert(!File.empty() && "Expected to find a valid file");
break;
}
if (Kind)
*Kind = LocKind;
auto Unit = Lib->FindOrCreateModule(marshalString<E_UTF8>(File));
if (LocKind != SourceLocationKind::Invalid)
Unit->IsSystemHeader = SM.isInSystemHeader(Loc);
return Unit;
}
//-----------------------------------//
void Parser::WalkMacros(clang::PreprocessingRecord* PR) void Parser::WalkMacros(clang::PreprocessingRecord* PR)
{ {
using namespace clang; using namespace clang;
@ -1424,7 +1429,7 @@ void Parser::WalkMacros(clang::PreprocessingRecord* PR)
macro->Name = marshalString<E_UTF8>(II->getName())->Trim(); macro->Name = marshalString<E_UTF8>(II->getName())->Trim();
macro->Expression = marshalString<E_UTF8>(Expression)->Trim(); macro->Expression = marshalString<E_UTF8>(Expression)->Trim();
auto M = GetModule(BeginExpr); auto M = GetTranslationUnit(BeginExpr);
if( M != nullptr ) if( M != nullptr )
M->Macros->Add(macro); M->Macros->Add(macro);

8
src/Parser/Parser.h

@ -159,10 +159,12 @@ protected:
void HandlePreprocessedEntities(clang::Decl* D, CppSharp::Declaration^); void HandlePreprocessedEntities(clang::Decl* D, CppSharp::Declaration^);
bool GetPreprocessedEntityText(clang::PreprocessedEntity*, std::string& Text); bool GetPreprocessedEntityText(clang::PreprocessedEntity*, std::string& Text);
CppSharp::TranslationUnit^ GetTranslationUnit(clang::SourceLocation Loc,
CppSharp::TranslationUnit^ GetModule(clang::SourceLocation Loc,
SourceLocationKind *Kind = 0); SourceLocationKind *Kind = 0);
CppSharp::Namespace^ GetNamespace(const clang::NamedDecl*); CppSharp::TranslationUnit^ GetTranslationUnit(const clang::Decl*);
CppSharp::DeclarationContext^ GetNamespace(clang::Decl*, clang::DeclContext*);
CppSharp::DeclarationContext^ GetNamespace(clang::Decl*);
clang::CallingConv GetAbiCallConv(clang::CallingConv CC, clang::CallingConv GetAbiCallConv(clang::CallingConv CC,
bool IsInstMethod, bool IsVariadic); bool IsInstMethod, bool IsVariadic);

Loading…
Cancel
Save