From 70dfd42e07b6aa80cf24a6b5140f37f72cb53e9d Mon Sep 17 00:00:00 2001 From: triton Date: Mon, 23 Jun 2014 22:26:01 +0100 Subject: [PATCH] Added support for C records to the parser. --- src/CppParser/Parser.cpp | 100 ++++++++++++++++++++++++++++++++++----- src/CppParser/Parser.h | 3 ++ 2 files changed, 90 insertions(+), 13 deletions(-) diff --git a/src/CppParser/Parser.cpp b/src/CppParser/Parser.cpp index a2372769..e3e74a62 100644 --- a/src/CppParser/Parser.cpp +++ b/src/CppParser/Parser.cpp @@ -554,9 +554,10 @@ void Parser::WalkVTable(clang::CXXRecordDecl* RD, Class* C) } } -Class* Parser::WalkRecordCXX(clang::CXXRecordDecl* Record) +Class* Parser::GetRecord(clang::RecordDecl* Record, bool& Process) { using namespace clang; + Process = false; if (Record->isInjectedClassName()) return nullptr; @@ -597,12 +598,39 @@ Class* Parser::WalkRecordCXX(clang::CXXRecordDecl* Record) if (!isCompleteDefinition) return RC; + Process = true; + return RC; + } + +Class* Parser::WalkRecord(clang::RecordDecl* Record) +{ + bool Process; + auto RC = GetRecord(Record, Process); + + if (!RC || !Process) + return RC; + + WalkRecord(Record, RC); + + return RC; +} + +Class* Parser::WalkRecordCXX(clang::CXXRecordDecl* Record) +{ + bool Process; + auto RC = GetRecord(Record, Process); + + if (!RC || !Process) + return RC; + WalkRecordCXX(Record, RC); return RC; } -void Parser::WalkRecordCXX(clang::CXXRecordDecl* Record, Class* RC) +static int I = 0; + +void Parser::WalkRecord(clang::RecordDecl* Record, Class* RC) { using namespace clang; @@ -617,18 +645,9 @@ void Parser::WalkRecordCXX(clang::CXXRecordDecl* Record, Class* RC) HandlePreprocessedEntities(RC, bodyRange, MacroLocation::ClassBody); auto &Sema = C->getSema(); - Sema.ForceDeclarationOfImplicitMembers(Record); - RC->IsPOD = Record->isPOD(); RC->IsUnion = Record->isUnion(); - RC->IsAbstract = Record->isAbstract(); RC->IsDependent = Record->isDependentType(); - RC->IsDynamic = Record->isDynamicClass(); - RC->IsPolymorphic = Record->isPolymorphic(); - RC->HasNonTrivialDefaultConstructor = Record->hasNonTrivialDefaultConstructor(); - RC->HasNonTrivialCopyConstructor = Record->hasNonTrivialCopyConstructor(); - RC->HasNonTrivialDestructor = Record->hasNonTrivialDestructor(); - RC->IsExternCContext = Record->isExternCContext(); bool hasLayout = !Record->isDependentType() && !Record->isInvalidDecl(); @@ -643,8 +662,6 @@ void Parser::WalkRecordCXX(clang::CXXRecordDecl* Record, Class* RC) RC->Layout->Alignment = (int)Layout-> getAlignment().getQuantity(); RC->Layout->Size = (int)Layout->getSize().getQuantity(); RC->Layout->DataSize = (int)Layout->getDataSize().getQuantity(); - RC->Layout->HasOwnVFPtr = Layout->hasOwnVFPtr(); - RC->Layout->VBPtrOffset = Layout->getVBPtrOffset().getQuantity(); } AccessSpecifierDecl* AccessDecl = nullptr; @@ -696,6 +713,37 @@ void Parser::WalkRecordCXX(clang::CXXRecordDecl* Record, Class* RC) break; } } } +} + +void Parser::WalkRecordCXX(clang::CXXRecordDecl* Record, Class* RC) +{ + using namespace clang; + + auto &Sema = C->getSema(); + Sema.ForceDeclarationOfImplicitMembers(Record); + + WalkRecord(Record, RC); + + RC->IsPOD = Record->isPOD(); + RC->IsAbstract = Record->isAbstract(); + RC->IsDynamic = Record->isDynamicClass(); + RC->IsPolymorphic = Record->isPolymorphic(); + RC->HasNonTrivialDefaultConstructor = Record->hasNonTrivialDefaultConstructor(); + RC->HasNonTrivialCopyConstructor = Record->hasNonTrivialCopyConstructor(); + RC->HasNonTrivialDestructor = Record->hasNonTrivialDestructor(); + + bool hasLayout = !Record->isDependentType() && !Record->isInvalidDecl(); + + // Get the record layout information. + const ASTRecordLayout* Layout = 0; + if (hasLayout) + { + Layout = &C->getASTContext().getASTRecordLayout(Record); + + assert (RC->Layout && "Expected a valid AST layout"); + RC->Layout->HasOwnVFPtr = Layout->hasOwnVFPtr(); + RC->Layout->VBPtrOffset = Layout->getVBPtrOffset().getQuantity(); + } // Iterate through the record bases. for(auto it = Record->bases_begin(); it != Record->bases_end(); ++it) @@ -1277,6 +1325,12 @@ DeclarationContext* Parser::GetNamespace(clang::Decl* D, const LinkageSpecDecl* LD = cast(Ctx); continue; } + case Decl::Record: + { + auto RD = cast(Ctx); + DC = WalkRecord(RD); + continue; + } case Decl::CXXRecord: { auto RD = cast(Ctx); @@ -2487,6 +2541,26 @@ Declaration* Parser::WalkDeclaration(clang::Decl* D, auto Kind = D->getKind(); switch(D->getKind()) { + case Decl::Record: + { + RecordDecl* RD = cast(D); + + auto Record = WalkRecord(RD); + + // We store a definition order index into the declarations. + // This is needed because declarations are added to their contexts as + // soon as they are referenced and we need to know the original order + // of the declarations. + + if (CanBeDefinition && Record->DefinitionOrder == 0) + { + Record->DefinitionOrder = Index++; + //Debug("%d: %s\n", Index++, GetTagDeclName(RD).c_str()); + } + + Decl = Record; + break; + } case Decl::CXXRecord: { CXXRecordDecl* RD = cast(D); diff --git a/src/CppParser/Parser.h b/src/CppParser/Parser.h index 8648a2bb..3da7670b 100644 --- a/src/CppParser/Parser.h +++ b/src/CppParser/Parser.h @@ -65,6 +65,9 @@ protected: Enumeration* WalkEnum(clang::EnumDecl* ED); Function* WalkFunction(clang::FunctionDecl* FD, bool IsDependent = false, bool AddToNamespace = true); + Class* GetRecord(clang::RecordDecl* Record, bool& IsComplete); + Class* WalkRecord(clang::RecordDecl* Record); + void WalkRecord(clang::RecordDecl* Record, Class* RC); Class* WalkRecordCXX(clang::CXXRecordDecl* Record); void WalkRecordCXX(clang::CXXRecordDecl* Record, Class* RC); ClassTemplateSpecialization*