fatal error: error opening file '<invalid loc>'

Hi,

I just started with Clang and already quite impressed with its capabilities J.

While trying to run the below program on .cpp file (say PrintFunctions.cpp) it is throwing up:

fatal error: error opening file ‘’

while ParseAST() is called. When I debugged, it is failing because of FID.ID == 0, in Preprocessor::EnterSourceFile().

I couldn’t get the root cause of the problem as the passing .cpp source file as argument seems to be fine.

Can somebody please help me fix the problem?

Thanks in advance,

Regards,

Manohar

The Program:

#include

#include

#include

#include

#include

#include

#include “clang/AST/ASTConsumer.h”

#include “clang/AST/RecursiveASTVisitor.h”

#include “clang/Basic/Diagnostic.h”

#include “clang/Basic/FileManager.h”

#include “clang/Basic/SourceManager.h”

#include “clang/Basic/TargetOptions.h”

#include “clang/Basic/TargetInfo.h”

#include “clang/Frontend/CompilerInstance.h”

#include “clang/Lex/Preprocessor.h”

#include “clang/Parse/ParseAST.h”

#include “clang/Rewrite/Core/Rewriter.h”

#include “clang/Rewrite/Frontend/Rewriters.h”

#include “llvm/Support/Host.h”

#include “llvm/Support/raw_ostream.h”

#include “clang/AST/Stmt.h”

using namespace clang;

using namespace std;

class MyASTVisitor : public RecursiveASTVisitor

{

public:

bool VisitStmt(Stmt *s) {

// Print name of sub‐class of s

printf(“\t%s\n”, s->getStmtClassName());

return true;

}

bool VisitFunctionDecl(FunctionDecl *f) {

// Print function name

printf(“%s\n”, f->getName());

return true;

}

};

class MyASTConsumer : public ASTConsumer

{

public:

MyASTConsumer()

: Visitor() //initialize MyASTVisitor

{}

virtual bool HandleTopLevelDecl(DeclGroupRef DR) {

for (DeclGroupRef::iterator b = DR.begin(), e = DR.end(); b != e; ++b) {

// Travel each function declaration using MyASTVisitor

Visitor.TraverseDecl(*b);

}

return true;

}

private:

MyASTVisitor Visitor;

};

int main(int argc, char *argv)

{

if (argc != 2) {

llvm::errs() << “Usage: PrintFunctions \n”;

return 1;

}

// CompilerInstance will hold the instance of the Clang compiler for us,

// managing the various objects needed to run the compiler.

CompilerInstance TheCompInst;

// Diagnostics manage problems and issues in compile

TheCompInst.createDiagnostics(NULL, false);

// Set target platform options

// Initialize target info with the default triple for our platform.

shared_ptr TO = make_shared();

//TargetOptions *TO = new TargetOptions();

TO->Triple = llvm::sys::getDefaultTargetTriple();

TargetInfo *TI = TargetInfo::CreateTargetInfo(TheCompInst.getDiagnostics(), TO);

TheCompInst.setTarget(TI);

// FileManager supports for file system lookup, file system caching, and directory search management.

TheCompInst.createFileManager();

FileManager &FileMgr = TheCompInst.getFileManager();

// SourceManager handles loading and caching of source files into memory.

TheCompInst.createSourceManager(FileMgr);

SourceManager &SourceMgr = TheCompInst.getSourceManager();

// Prreprocessor runs within a single source file

TheCompInst.createPreprocessor(TU_Complete);

// ASTContext holds long‐lived AST nodes (such as types and decls) .

TheCompInst.createASTContext();

// A Rewriter helps us manage the code rewriting task.

Rewriter TheRewriter;

TheRewriter.setSourceMgr(SourceMgr, TheCompInst.getLangOpts());

// Set the main file handled by the source manager to the input file.

const FileEntry *FileIn = FileMgr.getFile(argv[1]);

SourceMgr.createFileID(FileIn, SourceLocation(), SrcMgr::C_User); //SM: Changed from CreateMainFileID()

// Inform Diagnostics that processing of a source file is beginning.

TheCompInst.getDiagnosticClient().BeginSourceFile(TheCompInst.getLangOpts(),&TheCompInst.getPreprocessor());

// Create an AST consumer instance which is going to get called by ParseAST.

MyASTConsumer TheConsumer;

// Parse the file to AST, registering our consumer as the AST consumer.

ParseAST(TheCompInst.getPreprocessor(), &TheConsumer, TheCompInst.getASTContext());

return 0;

}

This is what we created libTooling for (http://clang.llvm.org/docs/LibTooling.html).

Hi Klimek,

Thanks for the quick reply. I was through with that LibTooling example and trying new things as given in the somewhat old tutorial at http://eli.thegreenplace.net/2012/06/08/basic-source-to-source-transformation-with-clang

It would be of great help if you could point out the root cause.

-Manohar

You probably want to follow this tutorial instead http://clang.llvm.org/docs/RAVFrontendAction.html

Hi Nikola,

Thanks for the reply. I already had practiced on the link you proposed.

My requirements are to provide the series of source files 1 by 1 and process them using Clang.

What will be the best way to achieve that?

Regards,

Manohar

You’ll want to use a ClangTool:
http://clang.llvm.org/doxygen/classclang_1_1tooling_1_1ClangTool.html