[cfe-dev] default include paths in the frontend

Sven Verdoolaege skimo-cfe at kotnet.org
Sun Nov 13 04:42:06 PST 2011


On Sun, Nov 13, 2011 at 12:38:48AM -0800, Argyrios Kyrtzidis wrote:
> Isn't this what "createInvocationFromCommandLine" in Frontend/Utils.h does ?

Thanks for the suggestion, but that doesn't seem to work very well
for me.

On Sun, Nov 13, 2011 at 01:17:52AM -0800, Chandler Carruth wrote:
> Aha! I vaguely remember we cribbed this from somewhere, but had forgotten
> where. We should probably extend that to fix up the InstalledDir in the
> driver...

Indeed, one of the problems is that there does not appear to be any
way of influencing ResourceDir when using createInvocationFromCommandLine.
Note though, that setting InstalledDir does not appear to have any effect
either as ResourceDir appears to be computed from "ClangExecutable" instead.

Another problem that I find when using createInvocationFromCommandLine
is that it appears to lead to an access to uninitialised values.
I'm probably calling this function in the wrong way, but it's not obvious
to me what exactly I'm doing wrong.

In particular, this code works for me:

static CompilerInvocation *construct_invocation(const char *filename,
        llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags)
{
        const char *binary = CLANG_PREFIX"/bin/clang";
        Driver *driver = new Driver(binary, llvm::sys::getDefaultTargetTriple(),
                            "", false, *Diags);
        std::vector<const char *> Argv;
        Argv.push_back(binary);
        Argv.push_back(filename);
        Compilation *compilation = driver->BuildCompilation(
                ArrayRef<const char *>(Argv));
        JobList &Jobs = compilation->getJobs();

        Command *cmd = cast<Command>(*Jobs.begin());
        const ArgStringList *args = &cmd->getArguments();

        CompilerInvocation *invocation = new CompilerInvocation;
        CompilerInvocation::CreateFromArgs(*invocation, args->data() + 1,
                                                args->data() + args->size(),
                                                *Diags);
        delete compilation;
        delete driver;
        return invocation;
}

This doesn't:

static CompilerInvocation *construct_invocation(const char *filename,
        llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags)
{
        return createInvocationFromCommandLine(ArrayRef<const char *>(filename),
                                                Diags);
}

Besides the ResourceDir problem, I get this warning from valgrind:

==14736== Conditional jump or move depends on uninitialised value(s)
==14736==    at 0x5CE52C2: clang::TextDiagnostic::emitIncludeStack(clang::SourceLocation, clang::DiagnosticsEngine::Level) (TextDiagnostic.cpp:546)
==14736==    by 0x5CE4E91: clang::TextDiagnostic::emitDiagnostic(clang::SourceLocation, clang::DiagnosticsEngine::Level, llvm::StringRef, llvm::ArrayRef<clang::CharSourceRange>, llvm::ArrayRef<clang::FixItHint>) (TextDiagnostic.cpp:437)
==14736==    by 0x5CA7A11: clang::TextDiagnosticPrinter::HandleDiagnostic(clang::DiagnosticsEngine::Level, clang::Diagnostic const&) (TextDiagnosticPrinter.cpp:182)
==14736==    by 0x638DB03: clang::DiagnosticIDs::ProcessDiag(clang::DiagnosticsEngine&) const (DiagnosticIDs.cpp:783)
==14736==    by 0x6386280: clang::DiagnosticsEngine::ProcessDiag() (Diagnostic.h:648)
==14736==    by 0x638368E: clang::DiagnosticBuilder::Emit() (Diagnostic.cpp:351)
==14736==    by 0x5C5EFF4: clang::DiagnosticBuilder::~DiagnosticBuilder() (Diagnostic.h:746)
==14736==    by 0x5C50164: clang::DiagnosticBuilder::~DiagnosticBuilder() (ArgList.cpp:0)
==14736==    by 0x634F33D: clang::Preprocessor::HandleIncludeDirective(clang::SourceLocation, clang::Token&, clang::DirectoryLookup const*, bool) (PPDirectives.cpp:1294)
==14736==    by 0x6350A39: clang::Preprocessor::HandleIncludeNextDirective(clang::SourceLocation, clang::Token&) (PPDirectives.cpp:1342)
==14736==    by 0x634DA81: clang::Preprocessor::HandleDirective(clang::Token&) (PPDirectives.cpp:651)
==14736==    by 0x633F23F: clang::Lexer::LexTokenInternal(clang::Token&) (Lexer.cpp:2933)
==14736==    by 0x633D30B: clang::Lexer::LexTokenInternal(clang::Token&) (Lexer.cpp:2327)

It also results in a memory leak, while the working code above does not
produce any warnings or memory leaks.

The calling context looks like this:

        CompilerInstance *Clang = new CompilerInstance();
        DiagnosticOptions DO;
        MyDiagnosticPrinter *printer = new MyDiagnosticPrinter(DO);
        llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
                Clang->createDiagnostics(DO, 0, NULL, printer);
        Clang->setDiagnostics(&*Diags);
        Diags->setSuppressSystemWarnings(true);
        CompilerInvocation *invocation = construct_invocation(filename, Diags);
	Clang->setInvocation(invocation);
        Clang->createFileManager();
        Clang->createSourceManager(Clang->getFileManager());
        TargetOptions TO;
        TO.Triple = llvm::sys::getDefaultTargetTriple();
        TargetInfo *target = TargetInfo::CreateTargetInfo(*Diags, TO);
        Clang->setTarget(target);
        CompilerInvocation::setLangDefaults(Clang->getLangOpts(), IK_C,
                                            LangStandard::lang_unspecified);
        Clang->createPreprocessor();
        Preprocessor &PP = Clang->getPreprocessor();
	...

skimo



More information about the cfe-dev mailing list