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. 70
      src/Parser/Parser.cpp
  2. 14
      src/Parser/Parser.h

70
src/Parser/Parser.cpp

@ -611,7 +611,13 @@ CppSharp::Namespace^ Parser::GetNamespace(const clang::NamedDecl* ND) @@ -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 @@ -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, "<built-in>"))
return false;
if(strcmp(FileName, "<built-in>") == 0)
return SourceLocationKind::Builtin;
// Also ignore declarations that come from system headers.
if (!IsUserLocation(SM, Loc))
return false;
if(strcmp(FileName, "<command line>") == 0)
return SourceLocationKind::CommandLine;
return true;
if(SM.getFileCharacteristic(Loc) == clang::SrcMgr::C_User)
return SourceLocationKind::User;
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() @@ -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,15 +1328,31 @@ CppSharp::TranslationUnit^ Parser::GetModule(clang::SourceLocation Loc) @@ -1316,15 +1328,31 @@ 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 = "<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;
@ -1366,7 +1394,7 @@ void Parser::WalkMacros(clang::PreprocessingRecord* PR) @@ -1366,7 +1394,7 @@ void Parser::WalkMacros(clang::PreprocessingRecord* PR)
auto Loc = MI->getDefinitionLoc();
if (!IsUserLocation(SM, Loc))
if (!IsValidDeclaration(Loc))
break;
SourceLocation BeginExpr =

14
src/Parser/Parser.h

@ -105,6 +105,15 @@ public ref struct ParserResult @@ -105,6 +105,15 @@ public ref struct ParserResult
List<ParserDiagnostic>^ Diagnostics;
};
enum class SourceLocationKind
{
Invalid,
Builtin,
CommandLine,
System,
User
};
struct Parser
{
Parser(ParserOptions^ Opts);
@ -139,6 +148,7 @@ protected: @@ -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: @@ -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,

Loading…
Cancel
Save