Browse Source

Completely rework the way we check for source locations to be more robust.

pull/1/head
triton 12 years ago
parent
commit
bc79dad205
  1. 72
      src/Parser/Parser.cpp
  2. 14
      src/Parser/Parser.h

72
src/Parser/Parser.cpp

@ -611,7 +611,13 @@ CppSharp::Namespace^ Parser::GetNamespace(const clang::NamedDecl* ND)
using namespace clix; using namespace clix;
SourceLocation Loc = ND->getLocation(); 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. // If the declaration is at global scope, just early exit.
const DeclContext *Ctx = ND->getDeclContext(); 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) SourceLocationKind Parser::GetLocationKind(const clang::SourceLocation& Loc)
{
auto Kind = SM.getFileCharacteristic(Loc);
return Kind == clang::SrcMgr::C_User;
}
bool Parser::IsValidDeclaration(const clang::SourceLocation& Loc)
{ {
using namespace clang; using namespace clang;
SourceManager& SM = C->getSourceManager(); SourceManager& SM = C->getSourceManager();
PresumedLoc PLoc = SM.getPresumedLoc(Loc); PresumedLoc PLoc = SM.getPresumedLoc(Loc);
if(PLoc.isInvalid())
return SourceLocationKind::Invalid;
const char *FileName = PLoc.getFilename(); const char *FileName = PLoc.getFilename();
// Igore built in declarations. if(strcmp(FileName, "<built-in>") == 0)
if(PLoc.isInvalid() || !strcmp(FileName, "<built-in>")) return SourceLocationKind::Builtin;
return false;
if(strcmp(FileName, "<command line>") == 0)
return SourceLocationKind::CommandLine;
// Also ignore declarations that come from system headers. if(SM.getFileCharacteristic(Loc) == clang::SrcMgr::C_User)
if (!IsUserLocation(SM, Loc)) return SourceLocationKind::User;
return false;
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 clang;
using namespace clix; using namespace clix;
@ -1316,16 +1328,32 @@ CppSharp::TranslationUnit^ Parser::GetModule(clang::SourceLocation Loc)
if (Loc.isMacroID()) if (Loc.isMacroID())
Loc = SM.getExpansionLoc(Loc); 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"); case SourceLocationKind::Invalid:
return nullptr; 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)); auto Unit = Lib->FindOrCreateModule(marshalString<E_UTF8>(File));
Unit->IsSystemHeader = SM.isInSystemHeader(Loc); if (LocKind != SourceLocationKind::Invalid)
Unit->IsSystemHeader = SM.isInSystemHeader(Loc);
return Unit; return Unit;
@ -1366,7 +1394,7 @@ void Parser::WalkMacros(clang::PreprocessingRecord* PR)
auto Loc = MI->getDefinitionLoc(); auto Loc = MI->getDefinitionLoc();
if (!IsUserLocation(SM, Loc)) if (!IsValidDeclaration(Loc))
break; break;
SourceLocation BeginExpr = SourceLocation BeginExpr =

14
src/Parser/Parser.h

@ -105,6 +105,15 @@ public ref struct ParserResult
List<ParserDiagnostic>^ Diagnostics; List<ParserDiagnostic>^ Diagnostics;
}; };
enum class SourceLocationKind
{
Invalid,
Builtin,
CommandLine,
System,
User
};
struct Parser struct Parser
{ {
Parser(ParserOptions^ Opts); Parser(ParserOptions^ Opts);
@ -139,6 +148,7 @@ protected:
bool DesugarType = false); bool DesugarType = false);
// Clang helpers // Clang helpers
SourceLocationKind GetLocationKind(const clang::SourceLocation& Loc);
bool IsValidDeclaration(const clang::SourceLocation& Loc); bool IsValidDeclaration(const clang::SourceLocation& Loc);
std::string GetDeclMangledName(clang::Decl*, clang::TargetCXXABI, std::string GetDeclMangledName(clang::Decl*, clang::TargetCXXABI,
bool IsDependent = false); bool IsDependent = false);
@ -149,7 +159,9 @@ 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^ GetModule(clang::SourceLocation Loc);
CppSharp::TranslationUnit^ GetModule(clang::SourceLocation Loc,
SourceLocationKind *Kind = 0);
CppSharp::Namespace^ GetNamespace(const clang::NamedDecl*); CppSharp::Namespace^ GetNamespace(const clang::NamedDecl*);
clang::CallingConv GetAbiCallConv(clang::CallingConv CC, clang::CallingConv GetAbiCallConv(clang::CallingConv CC,

Loading…
Cancel
Save