Browse Source

Improved the support for preprocessed entities.

pull/1/head
triton 12 years ago
parent
commit
c93dabe0c2
  1. 22
      src/Bridge/Declaration.cs
  2. 50
      src/Bridge/Preprocessor.cs
  3. 66
      src/Parser/Parser.cpp
  4. 3
      src/Parser/Parser.h

22
src/Bridge/Declaration.cs

@ -153,10 +153,14 @@ namespace CppSharp @@ -153,10 +153,14 @@ namespace CppSharp
// Passes that should not be run on this declaration.
public ISet<System.Type> ExcludeFromPasses;
// List of preprocessed entities attached to this declaration.
public IList<PreprocessedEntity> PreprocessedEntities;
protected Declaration()
{
IgnoreFlags = IgnoreFlags.None;
ExcludeFromPasses = new HashSet<System.Type>();
PreprocessedEntities = new List<PreprocessedEntity>();
}
protected Declaration(string name)
@ -187,24 +191,6 @@ namespace CppSharp @@ -187,24 +191,6 @@ namespace CppSharp
}
}
/// <summary>
/// Represents a C preprocessor macro definition.
/// </summary>
public class MacroDefinition : Declaration
{
// Contains the macro definition text.
public string Expression;
public MacroDefinition()
{
}
public override T Visit<T>(IDeclVisitor<T> visitor)
{
return visitor.VisitMacroDefinition(this);
}
}
public interface IDeclVisitor<out T>
{
T VisitDeclaration(Declaration decl);

50
src/Bridge/Preprocessor.cs

@ -0,0 +1,50 @@ @@ -0,0 +1,50 @@
namespace CppSharp
{
/// <summary>
/// Base class that describes a preprocessed entity, which may
/// be a preprocessor directive or macro expansion.
/// </summary>
public abstract class PreprocessedEntity : Declaration
{
}
/// <summary>
/// Represents a C preprocessor macro expansion.
/// </summary>
public class MacroExpansion : PreprocessedEntity
{
// Contains the macro expansion text.
public string Text;
public MacroDefinition Definition;
public MacroExpansion()
{
}
public override T Visit<T>(IDeclVisitor<T> visitor)
{
//return visitor.VisitMacroExpansion(this);
return default(T);
}
}
/// <summary>
/// Represents a C preprocessor macro definition.
/// </summary>
public class MacroDefinition : PreprocessedEntity
{
// Contains the macro definition text.
public string Expression;
public MacroDefinition()
{
}
public override T Visit<T>(IDeclVisitor<T> visitor)
{
return visitor.VisitMacroDefinition(this);
}
}
}

66
src/Parser/Parser.cpp

@ -1409,6 +1409,64 @@ void Parser::HandleComments(clang::Decl* D, CppSharp::Declaration^ Decl) @@ -1409,6 +1409,64 @@ void Parser::HandleComments(clang::Decl* D, CppSharp::Declaration^ Decl)
//-----------------------------------//
bool Parser::GetPreprocessedEntityText(clang::PreprocessedEntity* PE, std::string& Text)
{
using namespace clang;
SourceManager& SM = C->getSourceManager();
const LangOptions &LangOpts = C->getLangOpts();
auto Range = CharSourceRange::getTokenRange(PE->getSourceRange());
bool Invalid;
Text = Lexer::getSourceText(Range, SM, LangOpts, &Invalid);
return !Invalid && !Text.empty();
}
void Parser::HandlePreprocessedEntities(clang::Decl* D, CppSharp::Declaration^ Decl)
{
using namespace clang;
auto PPRecord = C->getPreprocessor().getPreprocessingRecord();
auto SourceRange = D->getSourceRange();
auto Range = PPRecord->getPreprocessedEntitiesInRange(SourceRange);
for (auto it = Range.first; it != Range.second; ++it)
{
PreprocessedEntity* PPEntity = (*it);
CppSharp::PreprocessedEntity^ Entity;
switch(PPEntity->getKind())
{
case PreprocessedEntity::MacroExpansionKind:
{
const MacroExpansion* MD = cast<MacroExpansion>(PPEntity);
Entity = gcnew CppSharp::MacroExpansion();
std::string Text;
if (!GetPreprocessedEntityText(PPEntity, Text))
continue;
static_cast<CppSharp::MacroExpansion^>(Entity)->Text =
clix::marshalString<clix::E_UTF8>(Text);
break;
}
case PreprocessedEntity::MacroDefinitionKind:
{
const MacroDefinition* MD = cast<MacroDefinition>(PPEntity);
Entity = gcnew CppSharp::MacroDefinition();
break;
}
default:
break;
}
Decl->PreprocessedEntities->Add(Entity);
}
}
//-----------------------------------//
CppSharp::Declaration^ Parser::WalkDeclarationDef(clang::Decl* D)
{
return WalkDeclaration(D, 0, /*IgnoreSystemDecls=*/true,
@ -1622,6 +1680,14 @@ CppSharp::Declaration^ Parser::WalkDeclaration(clang::Decl* D, clang::TypeLoc* T @@ -1622,6 +1680,14 @@ CppSharp::Declaration^ Parser::WalkDeclaration(clang::Decl* D, clang::TypeLoc* T
break;
} };
if (Decl)
{
HandlePreprocessedEntities(D, Decl);
if (const ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D))
Decl->IsDependent = VD->getType()->isDependentType();
}
return Decl;
}

3
src/Parser/Parser.h

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
#include <clang/AST/Mangle.h>
#include <clang/AST/RecordLayout.h>
#include <clang/Lex/Preprocessor.h>
#include <clang/Lex/PreprocessingRecord.h>
#include <clang/Parse/ParseAST.h>
#include <clang/Sema/Sema.h>
#include "CXXABI.h"
@ -131,6 +132,8 @@ protected: @@ -131,6 +132,8 @@ protected:
void HandleComments(clang::Decl* D, CppSharp::Declaration^);
void WalkFunction(clang::FunctionDecl* FD, CppSharp::Function^ F,
bool IsDependent = false);
void HandlePreprocessedEntities(clang::Decl* D, CppSharp::Declaration^);
bool GetPreprocessedEntityText(clang::PreprocessedEntity*, std::string& Text);
CppSharp::TranslationUnit^ GetModule(clang::SourceLocation Loc);
CppSharp::Namespace^ GetNamespace(const clang::NamedDecl*);

Loading…
Cancel
Save