diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 30e89917..067938fa 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -611,7 +611,13 @@ CppSharp::Namespace^ Parser::GetNamespace(const clang::NamedDecl* ND) using namespace clix; SourceLocation Loc = ND->getLocation(); - CppSharp::TranslationUnit^ M = GetModule(Loc); + + SourceLocationKind Kind; + CppSharp::TranslationUnit^ M = GetModule(Loc, &Kind); + + if (Kind == SourceLocationKind::Builtin || + Kind == SourceLocationKind::CommandLine) + return M; // If the declaration is at global scope, just early exit. const DeclContext *Ctx = ND->getDeclContext(); @@ -1251,30 +1257,35 @@ CppSharp::Function^ Parser::WalkFunction(clang::FunctionDecl* FD, bool IsDepende //-----------------------------------// -static bool IsUserLocation(clang::SourceManager& SM, clang::SourceLocation Loc) -{ - auto Kind = SM.getFileCharacteristic(Loc); - return Kind == clang::SrcMgr::C_User; -} - -bool Parser::IsValidDeclaration(const clang::SourceLocation& Loc) +SourceLocationKind Parser::GetLocationKind(const clang::SourceLocation& Loc) { using namespace clang; SourceManager& SM = C->getSourceManager(); PresumedLoc PLoc = SM.getPresumedLoc(Loc); + if(PLoc.isInvalid()) + return SourceLocationKind::Invalid; + const char *FileName = PLoc.getFilename(); - // Igore built in declarations. - if(PLoc.isInvalid() || !strcmp(FileName, "")) - return false; + if(strcmp(FileName, "") == 0) + return SourceLocationKind::Builtin; + + if(strcmp(FileName, "") == 0) + return SourceLocationKind::CommandLine; - // Also ignore declarations that come from system headers. - if (!IsUserLocation(SM, Loc)) - return false; + if(SM.getFileCharacteristic(Loc) == clang::SrcMgr::C_User) + return SourceLocationKind::User; - return true; + return SourceLocationKind::System; +} + +bool Parser::IsValidDeclaration(const clang::SourceLocation& Loc) +{ + auto Kind = GetLocationKind(Loc); + + return Kind == SourceLocationKind::User; } //-----------------------------------// @@ -1306,7 +1317,8 @@ void Parser::WalkAST() //-----------------------------------// -CppSharp::TranslationUnit^ Parser::GetModule(clang::SourceLocation Loc) +CppSharp::TranslationUnit^ Parser::GetModule(clang::SourceLocation Loc, + SourceLocationKind *Kind) { using namespace clang; using namespace clix; @@ -1316,16 +1328,32 @@ CppSharp::TranslationUnit^ Parser::GetModule(clang::SourceLocation Loc) if (Loc.isMacroID()) Loc = SM.getExpansionLoc(Loc); - StringRef File = SM.getFilename(Loc); + StringRef File; - if (!File.data() || File.empty()) + auto LocKind = GetLocationKind(Loc); + switch(LocKind) { - assert(0 && "Expected to find a valid file"); - return nullptr; + case SourceLocationKind::Invalid: + File = ""; + break; + case SourceLocationKind::Builtin: + File = ""; + break; + case SourceLocationKind::CommandLine: + File = ""; + 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(File)); - Unit->IsSystemHeader = SM.isInSystemHeader(Loc); + if (LocKind != SourceLocationKind::Invalid) + Unit->IsSystemHeader = SM.isInSystemHeader(Loc); return Unit; @@ -1366,7 +1394,7 @@ void Parser::WalkMacros(clang::PreprocessingRecord* PR) auto Loc = MI->getDefinitionLoc(); - if (!IsUserLocation(SM, Loc)) + if (!IsValidDeclaration(Loc)) break; SourceLocation BeginExpr = diff --git a/src/Parser/Parser.h b/src/Parser/Parser.h index 9ed3fdaf..db06fee0 100644 --- a/src/Parser/Parser.h +++ b/src/Parser/Parser.h @@ -105,6 +105,15 @@ public ref struct ParserResult List^ Diagnostics; }; +enum class SourceLocationKind +{ + Invalid, + Builtin, + CommandLine, + System, + User +}; + struct Parser { Parser(ParserOptions^ Opts); @@ -139,6 +148,7 @@ protected: bool DesugarType = false); // Clang helpers + SourceLocationKind GetLocationKind(const clang::SourceLocation& Loc); bool IsValidDeclaration(const clang::SourceLocation& Loc); std::string GetDeclMangledName(clang::Decl*, clang::TargetCXXABI, bool IsDependent = false); @@ -149,7 +159,9 @@ protected: void HandlePreprocessedEntities(clang::Decl* D, CppSharp::Declaration^); bool GetPreprocessedEntityText(clang::PreprocessedEntity*, std::string& Text); - CppSharp::TranslationUnit^ GetModule(clang::SourceLocation Loc); + + CppSharp::TranslationUnit^ GetModule(clang::SourceLocation Loc, + SourceLocationKind *Kind = 0); CppSharp::Namespace^ GetNamespace(const clang::NamedDecl*); clang::CallingConv GetAbiCallConv(clang::CallingConv CC,