├── .gitignore ├── CIBasicRecursiveASTVisitor.cpp ├── CIrewriter.cpp ├── CItutorial1.cpp ├── CItutorial2.cpp ├── CItutorial3.cpp ├── CItutorial4.cpp ├── CItutorial6.cpp ├── CREDITS.txt ├── CommentHandling.cpp ├── LICENSE.txt ├── README.markdown ├── ToolingTutorial.cpp ├── Win ├── CItutorial1 │ └── CItutorial1.vcxproj ├── CItutorial2 │ └── CItutorial2.vcxproj ├── CItutorial3 │ └── CItutorial3.vcxproj ├── CItutorial4 │ └── CItutorial4.vcxproj ├── CItutorial6 │ └── CItutorial6.vcxproj ├── ClangTutorial.sln ├── SharedBuild │ ├── SharedBuild.targets │ └── SharedBuild.vcxproj ├── tutorial1 │ └── tutorial1.vcxproj ├── tutorial2 │ └── tutorial2.vcxproj ├── tutorial3 │ └── tutorial3.vcxproj ├── tutorial4 │ └── tutorial4.vcxproj └── tutorial6 │ └── tutorial6.vcxproj ├── compile_commands.json ├── input04.c ├── invalidInputTest.c ├── makefile ├── test.c ├── testInclude.c ├── test_rewriter.cpp ├── tutorial1.cpp ├── tutorial2.cpp ├── tutorial3.cpp ├── tutorial4.cpp └── tutorial6.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | *.user 2 | *.filters 3 | *.suo 4 | *sdf 5 | *.aps 6 | *.o 7 | -------------------------------------------------------------------------------- /CIBasicRecursiveASTVisitor.cpp: -------------------------------------------------------------------------------- 1 | /*** CItutorial6.cpp ***************************************************** 2 | * This code is licensed under the New BSD license. 3 | * See LICENSE.txt for details. 4 | * 5 | * The CI tutorials remake the original tutorials but using the 6 | * CompilerInstance object which has as one of its purpose to create commonly 7 | * used Clang types. 8 | *****************************************************************************/ 9 | #include 10 | 11 | #include "llvm/Support/Host.h" 12 | #include "llvm/ADT/IntrusiveRefCntPtr.h" 13 | #include "llvm/Support/raw_ostream.h" 14 | 15 | #include "clang/Basic/DiagnosticOptions.h" 16 | #include "clang/Frontend/TextDiagnosticPrinter.h" 17 | #include "clang/Frontend/CompilerInstance.h" 18 | #include "clang/Basic/TargetOptions.h" 19 | #include "clang/Basic/TargetInfo.h" 20 | #include "clang/Basic/FileManager.h" 21 | #include "clang/Basic/SourceManager.h" 22 | #include "clang/Lex/Preprocessor.h" 23 | #include "clang/Basic/Diagnostic.h" 24 | #include "clang/AST/RecursiveASTVisitor.h" 25 | #include "clang/AST/ASTConsumer.h" 26 | #include "clang/Parse/ParseAST.h" 27 | 28 | 29 | // RecursiveASTVisitor is is the big-kahuna visitor that traverses 30 | // everything in the AST. 31 | class MyRecursiveASTVisitor 32 | : public clang::RecursiveASTVisitor { 33 | 34 | public: 35 | bool VisitTypedefDecl(clang::TypedefDecl *d); 36 | 37 | }; 38 | 39 | 40 | bool MyRecursiveASTVisitor::VisitTypedefDecl(clang::TypedefDecl *d) { 41 | llvm::errs() << "Visiting " << d->getDeclKindName() << " " 42 | << d->getName() << "\n"; 43 | return true; // returning false aborts the traversal 44 | } 45 | 46 | 47 | class MyASTConsumer : public clang::ASTConsumer { 48 | public: 49 | virtual bool HandleTopLevelDecl(clang::DeclGroupRef d); 50 | }; 51 | 52 | 53 | bool MyASTConsumer::HandleTopLevelDecl(clang::DeclGroupRef d) { 54 | MyRecursiveASTVisitor rv; 55 | typedef clang::DeclGroupRef::iterator iter; 56 | for (iter b = d.begin(), e = d.end(); b != e; ++b) { 57 | rv.TraverseDecl(*b); 58 | } 59 | return true; // keep going 60 | } 61 | 62 | 63 | int main() 64 | { 65 | using clang::CompilerInstance; 66 | using clang::TargetOptions; 67 | using clang::TargetInfo; 68 | using clang::FileEntry; 69 | using clang::DiagnosticOptions; 70 | using clang::TextDiagnosticPrinter; 71 | 72 | CompilerInstance ci; 73 | DiagnosticOptions diagnosticOptions; 74 | ci.createDiagnostics(); 75 | 76 | std::shared_ptr pto = std::make_shared(); 77 | pto->Triple = llvm::sys::getDefaultTargetTriple(); 78 | TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), pto); 79 | ci.setTarget(pti); 80 | 81 | ci.createFileManager(); 82 | ci.createSourceManager(ci.getFileManager()); 83 | ci.createPreprocessor(clang::TU_Complete); 84 | ci.getPreprocessorOpts().UsePredefines = false; 85 | ci.setASTConsumer(llvm::make_unique()); 86 | 87 | ci.createASTContext(); 88 | 89 | const FileEntry *pFile = ci.getFileManager().getFile("test.c"); 90 | ci.getSourceManager().setMainFileID( ci.getSourceManager().createFileID( pFile, clang::SourceLocation(), clang::SrcMgr::C_User)); 91 | ci.getDiagnosticClient().BeginSourceFile(ci.getLangOpts(), 92 | &ci.getPreprocessor()); 93 | clang::ParseAST(ci.getPreprocessor(), &ci.getASTConsumer(), ci.getASTContext()); 94 | ci.getDiagnosticClient().EndSourceFile(); 95 | 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /CIrewriter.cpp: -------------------------------------------------------------------------------- 1 | /*** CIrewriter.cpp ****************************************************** 2 | * This code is licensed under the New BSD license. 3 | * See LICENSE.txt for details. 4 | * 5 | * This tutorial was written by Robert Ankeney. 6 | * Send comments to rrankene@gmail.com. 7 | * 8 | * This tutorial is an example of using the Clang Rewriter class coupled 9 | * with the RecursiveASTVisitor class to parse and modify C code. 10 | * 11 | * Expressions of the form: 12 | * (expr1 && expr2) 13 | * are rewritten as: 14 | * L_AND(expr1, expr2) 15 | * and expressions of the form: 16 | * (expr1 || expr2) 17 | * are rewritten as: 18 | * L_OR(expr1, expr2) 19 | * 20 | * Functions are located and a comment is placed before and after the function. 21 | * 22 | * Statements of the type: 23 | * if (expr) 24 | * xxx; 25 | * else 26 | * yyy; 27 | * 28 | * are converted to: 29 | * if (expr) 30 | * { 31 | * xxx; 32 | * } 33 | * else 34 | * { 35 | * yyy; 36 | * } 37 | * 38 | * And similarly for while and for statements. 39 | * 40 | * Interesting information is printed on stderr. 41 | * 42 | * Usage: 43 | * CIrewriter .c 44 | * where allow for parameters to be passed to the preprocessor 45 | * such as -DFOO to define FOO. 46 | * 47 | * Generated as output _out.c 48 | * 49 | * Note: This tutorial uses the CompilerInstance object which has as one of 50 | * its purposes to create commonly used Clang types. 51 | *****************************************************************************/ 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | 58 | #include "llvm/Support/Host.h" 59 | #include "llvm/Support/raw_ostream.h" 60 | #include "llvm/ADT/IntrusiveRefCntPtr.h" 61 | #include "llvm/ADT/StringRef.h" 62 | #include "llvm/Support/FileSystem.h" 63 | 64 | #include "clang/Basic/DiagnosticOptions.h" 65 | #include "clang/Frontend/TextDiagnosticPrinter.h" 66 | #include "clang/Frontend/CompilerInstance.h" 67 | #include "clang/Basic/TargetOptions.h" 68 | #include "clang/Basic/TargetInfo.h" 69 | #include "clang/Basic/FileManager.h" 70 | #include "clang/Basic/SourceManager.h" 71 | #include "clang/Lex/Preprocessor.h" 72 | #include "clang/Lex/Lexer.h" 73 | #include "clang/Basic/Diagnostic.h" 74 | #include "clang/AST/RecursiveASTVisitor.h" 75 | #include "clang/AST/ASTConsumer.h" 76 | #include "clang/Parse/ParseAST.h" 77 | #include "clang/Rewrite/Frontend/Rewriters.h" 78 | #include "clang/Rewrite/Core/Rewriter.h" 79 | 80 | using namespace clang; 81 | 82 | // RecursiveASTVisitor is is the big-kahuna visitor that traverses 83 | // everything in the AST. 84 | class MyRecursiveASTVisitor 85 | : public RecursiveASTVisitor 86 | { 87 | 88 | public: 89 | MyRecursiveASTVisitor(Rewriter &R) : Rewrite(R) { } 90 | void InstrumentStmt(Stmt *s); 91 | bool VisitStmt(Stmt *s); 92 | bool VisitFunctionDecl(FunctionDecl *f); 93 | Expr *VisitBinaryOperator(BinaryOperator *op); 94 | 95 | Rewriter &Rewrite; 96 | }; 97 | 98 | // Override Binary Operator expressions 99 | Expr *MyRecursiveASTVisitor::VisitBinaryOperator(BinaryOperator *E) 100 | { 101 | // Determine type of binary operator 102 | if (E->isLogicalOp()) 103 | { 104 | // Insert function call at start of first expression. 105 | // Note getLocStart() should work as well as getExprLoc() 106 | Rewrite.InsertText(E->getLHS()->getExprLoc(), 107 | E->getOpcode() == BO_LAnd ? "L_AND(" : "L_OR(", true); 108 | 109 | // Replace operator ("||" or "&&") with "," 110 | Rewrite.ReplaceText(E->getOperatorLoc(), E->getOpcodeStr().size(), ","); 111 | 112 | // Insert closing paren at end of right-hand expression 113 | Rewrite.InsertTextAfterToken(E->getRHS()->getLocEnd(), ")"); 114 | } 115 | else 116 | // Note isComparisonOp() is like isRelationalOp() but includes == and != 117 | if (E->isRelationalOp()) 118 | { 119 | llvm::errs() << "Relational Op " << E->getOpcodeStr() << "\n"; 120 | } 121 | else 122 | // Handles == and != comparisons 123 | if (E->isEqualityOp()) 124 | { 125 | llvm::errs() << "Equality Op " << E->getOpcodeStr() << "\n"; 126 | } 127 | 128 | return E; 129 | } 130 | 131 | // InstrumentStmt - Add braces to line of code 132 | void MyRecursiveASTVisitor::InstrumentStmt(Stmt *s) 133 | { 134 | // Only perform if statement is not compound 135 | if (!isa(s)) 136 | { 137 | SourceLocation ST = s->getLocStart(); 138 | 139 | // Insert opening brace. Note the second true parameter to InsertText() 140 | // says to indent. Sadly, it will indent to the line after the if, giving: 141 | // if (expr) 142 | // { 143 | // stmt; 144 | // } 145 | Rewrite.InsertText(ST, "{\n", true, true); 146 | 147 | // Note Stmt::getLocEnd() returns the source location prior to the 148 | // token at the end of the line. For instance, for: 149 | // var = 123; 150 | // ^---- getLocEnd() points here. 151 | 152 | SourceLocation END = s->getLocEnd(); 153 | 154 | // MeasureTokenLength gets us past the last token, and adding 1 gets 155 | // us past the ';'. 156 | int offset = Lexer::MeasureTokenLength(END, 157 | Rewrite.getSourceMgr(), 158 | Rewrite.getLangOpts()) + 1; 159 | 160 | SourceLocation END1 = END.getLocWithOffset(offset); 161 | Rewrite.InsertText(END1, "\n}", true, true); 162 | } 163 | 164 | // Also note getLocEnd() on a CompoundStmt points ahead of the '}'. 165 | // Use getLocEnd().getLocWithOffset(1) to point past it. 166 | } 167 | 168 | // Override Statements which includes expressions and more 169 | bool MyRecursiveASTVisitor::VisitStmt(Stmt *s) 170 | { 171 | if (isa(s)) 172 | { 173 | // Cast s to IfStmt to access the then and else clauses 174 | IfStmt *If = cast(s); 175 | Stmt *TH = If->getThen(); 176 | 177 | // Add braces if needed to then clause 178 | InstrumentStmt(TH); 179 | 180 | Stmt *EL = If->getElse(); 181 | if (EL) 182 | { 183 | // Add braces if needed to else clause 184 | InstrumentStmt(EL); 185 | } 186 | } 187 | else 188 | if (isa(s)) 189 | { 190 | WhileStmt *While = cast(s); 191 | Stmt *BODY = While->getBody(); 192 | InstrumentStmt(BODY); 193 | } 194 | else 195 | if (isa(s)) 196 | { 197 | ForStmt *For = cast(s); 198 | Stmt *BODY = For->getBody(); 199 | InstrumentStmt(BODY); 200 | } 201 | 202 | return true; // returning false aborts the traversal 203 | } 204 | 205 | bool MyRecursiveASTVisitor::VisitFunctionDecl(FunctionDecl *f) 206 | { 207 | if (f->hasBody()) 208 | { 209 | SourceRange sr = f->getSourceRange(); 210 | Stmt *s = f->getBody(); 211 | 212 | // Make a stab at determining return type 213 | // Getting actual return type is trickier 214 | QualType q = f->getReturnType(); 215 | const Type *typ = q.getTypePtr(); 216 | 217 | std::string ret; 218 | if (typ->isVoidType()) 219 | ret = "void"; 220 | else 221 | if (typ->isIntegerType()) 222 | ret = "integer"; 223 | else 224 | if (typ->isCharType()) 225 | ret = "char"; 226 | else 227 | ret = "Other"; 228 | 229 | // Get name of function 230 | DeclarationNameInfo dni = f->getNameInfo(); 231 | DeclarationName dn = dni.getName(); 232 | std::string fname = dn.getAsString(); 233 | 234 | // Point to start of function declaration 235 | SourceLocation ST = sr.getBegin(); 236 | 237 | // Add comment 238 | char fc[256]; 239 | sprintf(fc, "// Begin function %s returning %s\n", fname.data(), ret.data()); 240 | Rewrite.InsertText(ST, fc, true, true); 241 | 242 | if (f->isMain()) 243 | llvm::errs() << "Found main()\n"; 244 | 245 | SourceLocation END = s->getLocEnd().getLocWithOffset(1); 246 | sprintf(fc, "\n// End function %s\n", fname.data()); 247 | Rewrite.InsertText(END, fc, true, true); 248 | } 249 | 250 | return true; // returning false aborts the traversal 251 | } 252 | 253 | class MyASTConsumer : public ASTConsumer 254 | { 255 | public: 256 | 257 | MyASTConsumer(Rewriter &Rewrite) : rv(Rewrite) { } 258 | virtual bool HandleTopLevelDecl(DeclGroupRef d); 259 | 260 | MyRecursiveASTVisitor rv; 261 | }; 262 | 263 | 264 | bool MyASTConsumer::HandleTopLevelDecl(DeclGroupRef d) 265 | { 266 | typedef DeclGroupRef::iterator iter; 267 | 268 | for (iter b = d.begin(), e = d.end(); b != e; ++b) 269 | { 270 | rv.TraverseDecl(*b); 271 | } 272 | 273 | return true; // keep going 274 | } 275 | 276 | 277 | int main(int argc, char **argv) 278 | { 279 | struct stat sb; 280 | 281 | if (argc < 2) 282 | { 283 | llvm::errs() << "Usage: CIrewriter \n"; 284 | return 1; 285 | } 286 | 287 | // Get filename 288 | std::string fileName(argv[argc - 1]); 289 | 290 | // Make sure it exists 291 | if (stat(fileName.c_str(), &sb) == -1) 292 | { 293 | perror(fileName.c_str()); 294 | exit(EXIT_FAILURE); 295 | } 296 | 297 | CompilerInstance compiler; 298 | DiagnosticOptions diagnosticOptions; 299 | compiler.createDiagnostics(); 300 | //compiler.createDiagnostics(argc, argv); 301 | 302 | // Create an invocation that passes any flags to preprocessor 303 | CompilerInvocation *Invocation = new CompilerInvocation; 304 | CompilerInvocation::CreateFromArgs(*Invocation, argv + 1, argv + argc, 305 | compiler.getDiagnostics()); 306 | compiler.setInvocation(Invocation); 307 | 308 | // Set default target triple 309 | std::shared_ptr pto = std::make_shared(); 310 | pto->Triple = llvm::sys::getDefaultTargetTriple(); 311 | TargetInfo *pti = TargetInfo::CreateTargetInfo(compiler.getDiagnostics(), pto); 312 | compiler.setTarget(pti); 313 | 314 | compiler.createFileManager(); 315 | compiler.createSourceManager(compiler.getFileManager()); 316 | 317 | HeaderSearchOptions &headerSearchOptions = compiler.getHeaderSearchOpts(); 318 | 319 | // -- Platform Specific Code lives here 320 | // This depends on A) that you're running linux and 321 | // B) that you have the same GCC LIBs installed that 322 | // I do. 323 | // Search through Clang itself for something like this, 324 | // go on, you won't find it. The reason why is Clang 325 | // has its own versions of std* which are installed under 326 | // /usr/local/lib/clang//include/ 327 | // See somewhere around Driver.cpp:77 to see Clang adding 328 | // its version of the headers to its include path. 329 | // To see what include paths need to be here, try 330 | // clang -v -c test.c 331 | // or clang++ for C++ paths as used below: 332 | headerSearchOptions.AddPath("/usr/include/c++/4.6", 333 | clang::frontend::Angled, 334 | false, 335 | false); 336 | headerSearchOptions.AddPath("/usr/include/c++/4.6/i686-linux-gnu", 337 | clang::frontend::Angled, 338 | false, 339 | false); 340 | headerSearchOptions.AddPath("/usr/include/c++/4.6/backward", 341 | clang::frontend::Angled, 342 | false, 343 | false); 344 | headerSearchOptions.AddPath("/usr/local/include", 345 | clang::frontend::Angled, 346 | false, 347 | false); 348 | headerSearchOptions.AddPath("/usr/local/lib/clang/3.3/include", 349 | clang::frontend::Angled, 350 | false, 351 | false); 352 | headerSearchOptions.AddPath("/usr/include/i386-linux-gnu", 353 | clang::frontend::Angled, 354 | false, 355 | false); 356 | headerSearchOptions.AddPath("/usr/include", 357 | clang::frontend::Angled, 358 | false, 359 | false); 360 | // -- End of Platform Specific Code 361 | 362 | 363 | // Allow C++ code to get rewritten 364 | LangOptions langOpts; 365 | langOpts.GNUMode = 1; 366 | langOpts.CXXExceptions = 1; 367 | langOpts.RTTI = 1; 368 | langOpts.Bool = 1; 369 | langOpts.CPlusPlus = 1; 370 | Invocation->setLangDefaults(langOpts, 371 | clang::IK_CXX, 372 | clang::LangStandard::lang_cxx0x); 373 | 374 | compiler.createPreprocessor(clang::TU_Complete); 375 | compiler.getPreprocessorOpts().UsePredefines = false; 376 | 377 | compiler.createASTContext(); 378 | 379 | // Initialize rewriter 380 | Rewriter Rewrite; 381 | Rewrite.setSourceMgr(compiler.getSourceManager(), compiler.getLangOpts()); 382 | 383 | const FileEntry *pFile = compiler.getFileManager().getFile(fileName); 384 | compiler.getSourceManager().setMainFileID( compiler.getSourceManager().createFileID( pFile, clang::SourceLocation(), clang::SrcMgr::C_User)); 385 | compiler.getDiagnosticClient().BeginSourceFile(compiler.getLangOpts(), 386 | &compiler.getPreprocessor()); 387 | 388 | MyASTConsumer astConsumer(Rewrite); 389 | 390 | // Convert .c to .c 391 | std::string outName (fileName); 392 | size_t ext = outName.rfind("."); 393 | if (ext == std::string::npos) 394 | ext = outName.length(); 395 | outName.insert(ext, "_out"); 396 | 397 | llvm::errs() << "Output to: " << outName << "\n"; 398 | std::error_code OutErrorInfo; 399 | std::error_code ok; 400 | llvm::raw_fd_ostream outFile(llvm::StringRef(outName), OutErrorInfo, llvm::sys::fs::F_None); 401 | 402 | if (OutErrorInfo == ok) 403 | { 404 | // Parse the AST 405 | ParseAST(compiler.getPreprocessor(), &astConsumer, compiler.getASTContext()); 406 | compiler.getDiagnosticClient().EndSourceFile(); 407 | 408 | // Output some #ifdefs 409 | outFile << "#define L_AND(a, b) a && b\n"; 410 | outFile << "#define L_OR(a, b) a || b\n\n"; 411 | 412 | // Now output rewritten source code 413 | const RewriteBuffer *RewriteBuf = 414 | Rewrite.getRewriteBufferFor(compiler.getSourceManager().getMainFileID()); 415 | outFile << std::string(RewriteBuf->begin(), RewriteBuf->end()); 416 | } 417 | else 418 | { 419 | llvm::errs() << "Cannot open " << outName << " for writing\n"; 420 | } 421 | 422 | outFile.close(); 423 | 424 | return 0; 425 | } 426 | 427 | -------------------------------------------------------------------------------- /CItutorial1.cpp: -------------------------------------------------------------------------------- 1 | /*** CItutorial1.cpp ***************************************************** 2 | * This code is licensed under the New BSD license. 3 | * See LICENSE.txt for details. 4 | * 5 | * The _CI tutorials remake the original tutorials but using the 6 | * CompilerInstance object which has as one of its purpose to create commonly 7 | * used Clang types. 8 | *****************************************************************************/ 9 | #include "llvm/Support/Host.h" 10 | #include "llvm/ADT/IntrusiveRefCntPtr.h" 11 | 12 | #include "clang/Basic/DiagnosticOptions.h" 13 | #include "clang/Frontend/TextDiagnosticPrinter.h" 14 | #include "clang/Frontend/CompilerInstance.h" 15 | #include "clang/Basic/TargetOptions.h" 16 | #include "clang/Basic/TargetInfo.h" 17 | 18 | /****************************************************************************** 19 | * This tutorial just shows off the steps needed to build up to a Preprocessor 20 | * object. Note that the order below is important. 21 | *****************************************************************************/ 22 | int main() 23 | { 24 | using clang::CompilerInstance; 25 | using clang::TargetOptions; 26 | using clang::TargetInfo; 27 | using clang::DiagnosticOptions; 28 | using clang::TextDiagnosticPrinter; 29 | 30 | CompilerInstance ci; 31 | ci.createDiagnostics(); 32 | 33 | std::shared_ptr pto = std::make_shared(); 34 | pto->Triple = llvm::sys::getDefaultTargetTriple(); 35 | TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), pto); 36 | ci.setTarget(pti); 37 | 38 | ci.createFileManager(); 39 | ci.createSourceManager(ci.getFileManager()); 40 | ci.createPreprocessor(clang::TU_Complete); 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /CItutorial2.cpp: -------------------------------------------------------------------------------- 1 | /*** CItutorial2.cpp ***************************************************** 2 | * This code is licensed under the New BSD license. 3 | * See LICENSE.txt for details. 4 | * 5 | * The CI tutorials remake the original tutorials but using the 6 | * CompilerInstance object which has as one of its purpose to create commonly 7 | * used Clang types. 8 | *****************************************************************************/ 9 | #include 10 | 11 | #include "llvm/Support/Host.h" 12 | #include "llvm/ADT/IntrusiveRefCntPtr.h" 13 | 14 | #include "clang/Basic/DiagnosticOptions.h" 15 | #include "clang/Frontend/TextDiagnosticPrinter.h" 16 | #include "clang/Frontend/CompilerInstance.h" 17 | #include "clang/Basic/TargetOptions.h" 18 | #include "clang/Basic/TargetInfo.h" 19 | #include "clang/Basic/FileManager.h" 20 | #include "clang/Basic/SourceManager.h" 21 | #include "clang/Lex/Preprocessor.h" 22 | #include "clang/Basic/Diagnostic.h" 23 | 24 | /****************************************************************************** 25 | * 26 | *****************************************************************************/ 27 | int main() 28 | { 29 | using clang::CompilerInstance; 30 | using clang::TargetOptions; 31 | using clang::TargetInfo; 32 | using clang::FileEntry; 33 | using clang::Token; 34 | using clang::DiagnosticOptions; 35 | using clang::TextDiagnosticPrinter; 36 | 37 | CompilerInstance ci; 38 | DiagnosticOptions diagnosticOptions; 39 | ci.createDiagnostics(); 40 | 41 | std::shared_ptr pto = std::make_shared(); 42 | pto->Triple = llvm::sys::getDefaultTargetTriple(); 43 | TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), pto); 44 | ci.setTarget(pti); 45 | 46 | ci.createFileManager(); 47 | ci.createSourceManager(ci.getFileManager()); 48 | ci.createPreprocessor(clang::TU_Complete); 49 | 50 | const FileEntry *pFile = ci.getFileManager().getFile("test.c"); 51 | ci.getSourceManager().setMainFileID( ci.getSourceManager().createFileID( pFile, clang::SourceLocation(), clang::SrcMgr::C_User)); 52 | ci.getPreprocessor().EnterMainSourceFile(); 53 | ci.getDiagnosticClient().BeginSourceFile(ci.getLangOpts(), 54 | &ci.getPreprocessor()); 55 | Token tok; 56 | do { 57 | ci.getPreprocessor().Lex(tok); 58 | if( ci.getDiagnostics().hasErrorOccurred()) 59 | break; 60 | ci.getPreprocessor().DumpToken(tok); 61 | std::cerr << std::endl; 62 | } while ( tok.isNot(clang::tok::eof)); 63 | ci.getDiagnosticClient().EndSourceFile(); 64 | 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /CItutorial3.cpp: -------------------------------------------------------------------------------- 1 | /*** CItutorial3.cpp ***************************************************** 2 | * This code is licensed under the New BSD license. 3 | * See LICENSE.txt for details. 4 | * 5 | * The CI tutorials remake the original tutorials but using the 6 | * CompilerInstance object which has as one of its purpose to create commonly 7 | * used Clang types. 8 | *****************************************************************************/ 9 | #include 10 | 11 | #include "llvm/Support/Host.h" 12 | #include "llvm/ADT/IntrusiveRefCntPtr.h" 13 | 14 | #include "clang/Basic/DiagnosticOptions.h" 15 | #include "clang/Frontend/TextDiagnosticPrinter.h" 16 | #include "clang/Frontend/CompilerInstance.h" 17 | #include "clang/Basic/TargetOptions.h" 18 | #include "clang/Basic/TargetInfo.h" 19 | #include "clang/Basic/FileManager.h" 20 | #include "clang/Basic/SourceManager.h" 21 | #include "clang/Lex/Preprocessor.h" 22 | #include "clang/Basic/Diagnostic.h" 23 | #include "clang/Lex/HeaderSearch.h" 24 | #include "clang/Frontend/Utils.h" 25 | /****************************************************************************** 26 | * 27 | *****************************************************************************/ 28 | int main() 29 | { 30 | using clang::CompilerInstance; 31 | using clang::TargetOptions; 32 | using clang::TargetInfo; 33 | using clang::FileEntry; 34 | using clang::Token; 35 | using clang::HeaderSearch; 36 | using clang::HeaderSearchOptions; 37 | using clang::DiagnosticOptions; 38 | using clang::TextDiagnosticPrinter; 39 | 40 | CompilerInstance ci; 41 | DiagnosticOptions diagnosticOptions; 42 | ci.createDiagnostics(); 43 | 44 | std::shared_ptr pto = std::make_shared(); 45 | pto->Triple = llvm::sys::getDefaultTargetTriple(); 46 | TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), pto); 47 | ci.setTarget(pti); 48 | 49 | ci.createFileManager(); 50 | ci.createSourceManager(ci.getFileManager()); 51 | ci.createPreprocessor(clang::TU_Complete); 52 | ci.getPreprocessorOpts().UsePredefines = true; 53 | 54 | llvm::IntrusiveRefCntPtr hso( new clang::HeaderSearchOptions()); 55 | HeaderSearch headerSearch(hso, 56 | ci.getSourceManager(), 57 | ci.getDiagnostics(), 58 | ci.getLangOpts(), 59 | pti); 60 | 61 | // -- Platform Specific Code lives here 62 | // This depends on A) that you're running linux and 63 | // B) that you have the same GCC LIBs installed that 64 | // I do. 65 | // Search through Clang itself for something like this, 66 | // go on, you won't find it. The reason why is Clang 67 | // has its own versions of std* which are installed under 68 | // /usr/local/lib/clang//include/ 69 | // See somewhere around Driver.cpp:77 to see Clang adding 70 | // its version of the headers to its include path. 71 | hso->AddPath("/usr/include", 72 | clang::frontend::Angled, 73 | false, 74 | false); 75 | hso->AddPath("/usr/lib/gcc/x86_64-linux-gnu/4.4.5/include", 76 | clang::frontend::Angled, 77 | false, 78 | false); 79 | // -- End of Platform Specific Code 80 | 81 | clang::InitializePreprocessor(ci.getPreprocessor(), 82 | ci.getPreprocessorOpts(), 83 | ci.getFrontendOpts()); 84 | 85 | const FileEntry *pFile = ci.getFileManager().getFile("testInclude.c"); 86 | ci.getSourceManager().setMainFileID( ci.getSourceManager().createFileID( pFile, clang::SourceLocation(), clang::SrcMgr::C_User)); 87 | ci.getPreprocessor().EnterMainSourceFile(); 88 | ci.getDiagnosticClient().BeginSourceFile(ci.getLangOpts(), 89 | &ci.getPreprocessor()); 90 | Token tok; 91 | do { 92 | ci.getPreprocessor().Lex(tok); 93 | if( ci.getDiagnostics().hasErrorOccurred()) 94 | break; 95 | ci.getPreprocessor().DumpToken(tok); 96 | std::cerr << std::endl; 97 | } while ( tok.isNot(clang::tok::eof)); 98 | ci.getDiagnosticClient().EndSourceFile(); 99 | 100 | return 0; 101 | } 102 | -------------------------------------------------------------------------------- /CItutorial4.cpp: -------------------------------------------------------------------------------- 1 | /*** CItutorial4.cpp ***************************************************** 2 | * This code is licensed under the New BSD license. 3 | * See LICENSE.txt for details. 4 | * 5 | * The CI tutorials remake the original tutorials but using the 6 | * CompilerInstance object which has as one of its purpose to create commonly 7 | * used Clang types. 8 | *****************************************************************************/ 9 | #include 10 | 11 | #include "llvm/Support/Host.h" 12 | #include "llvm/ADT/IntrusiveRefCntPtr.h" 13 | 14 | #include "clang/Basic/DiagnosticOptions.h" 15 | #include "clang/Frontend/TextDiagnosticPrinter.h" 16 | #include "clang/Frontend/CompilerInstance.h" 17 | #include "clang/Basic/TargetOptions.h" 18 | #include "clang/Basic/TargetInfo.h" 19 | #include "clang/Basic/FileManager.h" 20 | #include "clang/Basic/SourceManager.h" 21 | #include "clang/Lex/Preprocessor.h" 22 | #include "clang/Basic/Diagnostic.h" 23 | #include "clang/AST/ASTContext.h" 24 | #include "clang/AST/ASTConsumer.h" 25 | #include "clang/Basic/LangOptions.h" 26 | #include "clang/Parse/Parser.h" 27 | #include "clang/Parse/ParseAST.h" 28 | 29 | /****************************************************************************** 30 | * 31 | *****************************************************************************/ 32 | int main() 33 | { 34 | using clang::CompilerInstance; 35 | using clang::TargetOptions; 36 | using clang::TargetInfo; 37 | using clang::FileEntry; 38 | using clang::Token; 39 | using clang::ASTContext; 40 | using clang::ASTConsumer; 41 | using clang::Parser; 42 | using clang::DiagnosticOptions; 43 | using clang::TextDiagnosticPrinter; 44 | 45 | CompilerInstance ci; 46 | DiagnosticOptions diagnosticOptions; 47 | ci.createDiagnostics(); 48 | 49 | std::shared_ptr pto = std::make_shared(); 50 | pto->Triple = llvm::sys::getDefaultTargetTriple(); 51 | TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), pto); 52 | ci.setTarget(pti); 53 | 54 | ci.createFileManager(); 55 | ci.createSourceManager(ci.getFileManager()); 56 | ci.createPreprocessor(clang::TU_Complete); 57 | ci.getPreprocessorOpts().UsePredefines = false; 58 | 59 | ci.setASTConsumer(llvm::make_unique()); 60 | 61 | ci.createASTContext(); 62 | ci.createSema(clang::TU_Complete, NULL); 63 | 64 | const FileEntry *pFile = ci.getFileManager().getFile("test.c"); 65 | ci.getSourceManager().setMainFileID( ci.getSourceManager().createFileID( pFile, clang::SourceLocation(), clang::SrcMgr::C_User)); 66 | clang::ParseAST(ci.getSema()); 67 | ci.getASTContext().Idents.PrintStats(); 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /CItutorial6.cpp: -------------------------------------------------------------------------------- 1 | /*** CItutorial6.cpp ***************************************************** 2 | * This code is licensed under the New BSD license. 3 | * See LICENSE.txt for details. 4 | * 5 | * The CI tutorials remake the original tutorials but using the 6 | * CompilerInstance object which has as one of its purpose to create commonly 7 | * used Clang types. 8 | *****************************************************************************/ 9 | #include 10 | 11 | #include "llvm/Support/Host.h" 12 | #include "llvm/ADT/IntrusiveRefCntPtr.h" 13 | 14 | #include "clang/Basic/DiagnosticOptions.h" 15 | #include "clang/Frontend/TextDiagnosticPrinter.h" 16 | #include "clang/Frontend/CompilerInstance.h" 17 | #include "clang/Basic/TargetOptions.h" 18 | #include "clang/Basic/TargetInfo.h" 19 | #include "clang/Basic/FileManager.h" 20 | #include "clang/Basic/SourceManager.h" 21 | #include "clang/Lex/Preprocessor.h" 22 | #include "clang/Basic/Diagnostic.h" 23 | #include "clang/AST/ASTContext.h" 24 | #include "clang/AST/ASTConsumer.h" 25 | #include "clang/Parse/Parser.h" 26 | #include "clang/Parse/ParseAST.h" 27 | 28 | /****************************************************************************** 29 | * 30 | *****************************************************************************/ 31 | class MyASTConsumer : public clang::ASTConsumer 32 | { 33 | public: 34 | MyASTConsumer() : clang::ASTConsumer() { } 35 | virtual ~MyASTConsumer() { } 36 | 37 | virtual bool HandleTopLevelDecl( clang::DeclGroupRef d) 38 | { 39 | static int count = 0; 40 | clang::DeclGroupRef::iterator it; 41 | for( it = d.begin(); it != d.end(); it++) 42 | { 43 | count++; 44 | clang::VarDecl *vd = llvm::dyn_cast(*it); 45 | if(!vd) 46 | { 47 | continue; 48 | } 49 | if( vd->isFileVarDecl() && !vd->hasExternalStorage() ) 50 | { 51 | std::cerr << "Read top-level variable decl: '"; 52 | std::cerr << vd->getDeclName().getAsString() ; 53 | std::cerr << std::endl; 54 | } 55 | } 56 | return true; 57 | } 58 | }; 59 | 60 | /****************************************************************************** 61 | * 62 | *****************************************************************************/ 63 | int main() 64 | { 65 | using clang::CompilerInstance; 66 | using clang::TargetOptions; 67 | using clang::TargetInfo; 68 | using clang::FileEntry; 69 | using clang::Token; 70 | using clang::ASTContext; 71 | using clang::ASTConsumer; 72 | using clang::Parser; 73 | using clang::DiagnosticOptions; 74 | using clang::TextDiagnosticPrinter; 75 | 76 | CompilerInstance ci; 77 | DiagnosticOptions diagnosticOptions; 78 | ci.createDiagnostics(); 79 | 80 | std::shared_ptr pto = std::make_shared(); 81 | pto->Triple = llvm::sys::getDefaultTargetTriple(); 82 | TargetInfo *pti = TargetInfo::CreateTargetInfo(ci.getDiagnostics(), pto); 83 | ci.setTarget(pti); 84 | 85 | ci.createFileManager(); 86 | ci.createSourceManager(ci.getFileManager()); 87 | ci.createPreprocessor(clang::TU_Complete); 88 | ci.getPreprocessorOpts().UsePredefines = false; 89 | ci.setASTConsumer(llvm::make_unique()); 90 | 91 | ci.createASTContext(); 92 | 93 | const FileEntry *pFile = ci.getFileManager().getFile("input04.c"); 94 | ci.getSourceManager().setMainFileID( ci.getSourceManager().createFileID( pFile, clang::SourceLocation(), clang::SrcMgr::C_User)); 95 | ci.getDiagnosticClient().BeginSourceFile(ci.getLangOpts(), 96 | &ci.getPreprocessor()); 97 | clang::ParseAST(ci.getPreprocessor(), &ci.getASTConsumer(), ci.getASTContext()); 98 | ci.getDiagnosticClient().EndSourceFile(); 99 | 100 | return 0; 101 | } 102 | -------------------------------------------------------------------------------- /CREDITS.txt: -------------------------------------------------------------------------------- 1 | Many thanks to: 2 | 3 | Nico Weber and Justin LaPre for initial versions of the tutorial 4 | -------------------------------------------------------------------------------- /CommentHandling.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "llvm/Support/CommandLine.h" 6 | 7 | #include "clang/Basic/SourceLocation.h" 8 | #include "clang/AST/ASTConsumer.h" 9 | #include "clang/AST/ASTContext.h" 10 | #include "clang/Parse/Parser.h" 11 | #include "clang/Frontend/CompilerInstance.h" 12 | #include "clang/Tooling/CommonOptionsParser.h" 13 | #include "clang/Tooling/Tooling.h" 14 | 15 | using namespace clang::driver; 16 | using namespace clang::tooling; 17 | using clang::FileID; 18 | 19 | static llvm::cl::OptionCategory MyToolCategory(""); 20 | 21 | /****************************************************************************** 22 | * 23 | *****************************************************************************/ 24 | namespace tooling { 25 | 26 | class MyCommentHandler : public clang::CommentHandler 27 | { 28 | private: 29 | llvm::StringRef m_inFile; 30 | 31 | public: 32 | 33 | void set_InFile(llvm::StringRef inFile) 34 | { 35 | m_inFile = inFile; 36 | } 37 | 38 | virtual bool HandleComment( clang::Preprocessor &pp, clang::SourceRange rng) 39 | { 40 | clang::SourceManager &sm = pp.getSourceManager(); 41 | if( sm.getFilename(rng.getBegin()) == m_inFile) 42 | { 43 | std::pair startLoc = sm.getDecomposedLoc(rng.getBegin()); 44 | std::pair endLoc = sm.getDecomposedLoc(rng.getEnd()); 45 | 46 | llvm::StringRef fileData = sm.getBufferData(startLoc.first); 47 | 48 | std::cout << fileData.substr(startLoc.second, endLoc.second - startLoc.second).str(); 49 | std::cout << std::endl; 50 | } 51 | return false; 52 | } 53 | }; 54 | 55 | /****************************************************************************** 56 | * 57 | *****************************************************************************/ 58 | class MyASTConsumer : public clang::ASTConsumer 59 | { 60 | public: 61 | MyASTConsumer() : clang::ASTConsumer() { } 62 | virtual ~MyASTConsumer() { } 63 | 64 | virtual bool HandleTopLevelDecl( clang::DeclGroupRef d) 65 | { 66 | static int count = 0; 67 | clang::DeclGroupRef::iterator it; 68 | for( it = d.begin(); it != d.end(); it++) 69 | { 70 | count++; 71 | clang::VarDecl *vd = llvm::dyn_cast(*it); 72 | if(!vd) 73 | { 74 | continue; 75 | } 76 | if( vd->isFileVarDecl() && !vd->hasExternalStorage() ) 77 | { 78 | std::cerr << "Read top-level variable decl: '"; 79 | std::cerr << vd->getDeclName().getAsString() ; 80 | std::cerr << std::endl; 81 | } 82 | } 83 | return true; 84 | } 85 | }; 86 | 87 | /****************************************************************************** 88 | * 89 | *****************************************************************************/ 90 | class MyFactory : public clang::ASTFrontendAction 91 | { 92 | private: 93 | MyCommentHandler ch; 94 | 95 | public: 96 | std::unique_ptr CreateASTConsumer(clang::CompilerInstance &ci, llvm::StringRef inFile) { 97 | ch.set_InFile(inFile); 98 | ci.getPreprocessor().addCommentHandler(&ch); 99 | return llvm::make_unique(); 100 | } 101 | 102 | }; 103 | 104 | } // Namespace tooling 105 | 106 | /****************************************************************************** 107 | * 108 | *****************************************************************************/ 109 | int main(int argc, const char **argv) 110 | { 111 | CommonOptionsParser OptionsParser(argc, argv, MyToolCategory); 112 | ClangTool Tool(OptionsParser.getCompilations(), 113 | OptionsParser.getSourcePathList()); 114 | std::unique_ptr factory = newFrontendActionFactory(); 115 | Tool.run(factory.get()); 116 | return 0; 117 | } 118 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | ============================================================================== 2 | Clang-tutorial License 3 | ============================================================================== 4 | This project is distributed under the terms of the "New BSD License". 5 | 6 | Copyright (c) 2010, Larry Olson 7 | All rights reserved. 8 | 9 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 14 | 15 | * Neither the name of Larry Olson nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 18 | 19 | ============================================================================== 20 | LLVM Release License 21 | ============================================================================== 22 | University of Illinois/NCSA 23 | Open Source License 24 | 25 | Copyright (c) 2003-2011 University of Illinois at Urbana-Champaign. 26 | All rights reserved. 27 | 28 | Developed by: 29 | 30 | LLVM Team 31 | 32 | University of Illinois at Urbana-Champaign 33 | 34 | http://llvm.org 35 | 36 | Permission is hereby granted, free of charge, to any person obtaining a copy of 37 | this software and associated documentation files (the "Software"), to deal with 38 | the Software without restriction, including without limitation the rights to 39 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 40 | of the Software, and to permit persons to whom the Software is furnished to do 41 | so, subject to the following conditions: 42 | 43 | * Redistributions of source code must retain the above copyright notice, 44 | this list of conditions and the following disclaimers. 45 | 46 | * Redistributions in binary form must reproduce the above copyright notice, 47 | this list of conditions and the following disclaimers in the 48 | documentation and/or other materials provided with the distribution. 49 | 50 | * Neither the names of the LLVM Team, University of Illinois at 51 | Urbana-Champaign, nor the names of its contributors may be used to 52 | endorse or promote products derived from this Software without specific 53 | prior written permission. 54 | 55 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 56 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 57 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 58 | CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 59 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 60 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE 61 | SOFTWARE. 62 | 63 | ============================================================================== 64 | Copyrights and Licenses for Third Party Software Distributed with LLVM: 65 | ============================================================================== 66 | The LLVM software contains code written by third parties. Such software will 67 | have its own individual LICENSE.TXT file in the directory in which it appears. 68 | This file will describe the copyrights, license, and restrictions which apply 69 | to that code. 70 | 71 | The disclaimer of warranty in the University of Illinois Open Source License 72 | applies to all code in the LLVM Distribution, and nothing in any of the 73 | other licenses gives permission to use the names of the LLVM Team or the 74 | University of Illinois to endorse or promote products derived from this 75 | Software. 76 | 77 | The following pieces of software have additional or alternate copyrights, 78 | licenses, and/or restrictions: 79 | 80 | Program Directory 81 | ------- --------- 82 | Autoconf llvm/autoconf 83 | llvm/projects/ModuleMaker/autoconf 84 | llvm/projects/sample/autoconf 85 | CellSPU backend llvm/lib/Target/CellSPU/README.txt 86 | Google Test llvm/utils/unittest/googletest 87 | OpenBSD regex llvm/lib/Support/{reg*, COPYRIGHT.regex} 88 | 89 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | # About # 2 | This is a collection of tutorials showing off how to use core Clang types. It is based directly on two older tutorials which no longer built due to code rot. 3 | 4 | 1. [tutorial 1](http://amnoid.de/tmp/clangtut/tut.html) by Nico Weber - 9/28/2008 5 | 2. [tutorial 2](http://www.cs.rpi.edu/~laprej/clang.html) by Justin LaPre at Rensselaer Polytechnic Institute - 10/20/2009 6 | 3. [tutorial 3](https://github.com/loarabia/Clang-tutorial/wiki/TutorialOrig) by Larry Olson - 4/14/2012 7 | 8 | This particular set of tutorials tracks the llvm / clang mainline and is updated semi-regularly to account for llvm / clang API changes. 9 | 10 | See contents of the links above for a walkthrough of what these tutorials are doing. 11 | 12 | # Last Update # 13 | This was last built on 5/25/2015 against 14 | URL: http://llvm.org/svn/llvm-project/llvm/trunk 15 | Revision:237487 16 | 17 | # Other Options # 18 | The Clang team has been hard at work making it easier to write tools using Clang. There are [4 options](http://clang.llvm.org/docs/Tooling.html) 19 | for developing tools using clang and llvm infrastructure. 20 | 21 | # Latest Stable LLVM / Clang (v3.4) # 22 | The master branch tracks recent commits to the clang and llvm svn. The tutorial assumes 23 | you have grabbed a copy of both llvm and clang by following [these instructions](http://clang.llvm.org/get_started.html) 24 | and that you have modified the makefile of this project to point to the build's resulting llvm-config. If you want 25 | the latest public release, then checkout the *3.4* branch. 26 | 27 | git clone git@github.com:loarabia/Clang-tutorial.git 28 | git checkout 3.4 29 | 30 | # CI tutorials # 31 | The tutorials prefixed with CI are the same as the original tutorials but use the CompilerInstance object and 32 | its helper methods to perform the same tasks as the original tutorials. For the most part, this makes the code 33 | much more compact. 34 | 35 | # Tooling tutorials # 36 | These tutorials (and the clang tooling infrastrucutre) depend on having a file called `compile_commands.json` which 37 | defines the commands used to compile the input file. You will need to modify this file's `directory` field to point 38 | to the absolute path of the Clang-tutorial on your storage. 39 | 40 | Update compile_commands.json to the directory containing input 41 | 42 | ./ToolingTutorial input04.c 43 | ./CommentHandling input04.c 44 | 45 | # Windows Build # 46 | Note on the Windows build: Currently the paths are hardcoded. Please see the SharedBuild.targets file 47 | inside of the SharedBuild project to update the path for your specific LLVM and CLANG install. 48 | 49 | In particular, the LLVMLibsDirs property and the LLVMIncludes property should be updated. 50 | 51 | # Contact Me # 52 | For any questions, please ping me via my github account. Changes and additions are always welcome. 53 | -------------------------------------------------------------------------------- /ToolingTutorial.cpp: -------------------------------------------------------------------------------- 1 | #if CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR == 5 2 | #define CLANG_3_5 3 | #endif 4 | #include 5 | #include 6 | 7 | #include "llvm/Support/CommandLine.h" 8 | 9 | #include "clang/AST/ASTConsumer.h" 10 | #include "clang/AST/ASTContext.h" 11 | #include "clang/Parse/Parser.h" 12 | #include "clang/Tooling/CommonOptionsParser.h" 13 | #include "clang/Tooling/Tooling.h" 14 | 15 | using namespace clang::driver; 16 | using namespace clang::tooling; 17 | 18 | static llvm::cl::OptionCategory MyToolCategory(""); 19 | /****************************************************************************** 20 | * 21 | *****************************************************************************/ 22 | namespace tooling { 23 | 24 | /****************************************************************************** 25 | * 26 | *****************************************************************************/ 27 | class MyASTConsumer : public clang::ASTConsumer 28 | { 29 | public: 30 | MyASTConsumer() : clang::ASTConsumer() { } 31 | virtual ~MyASTConsumer() { } 32 | 33 | virtual bool HandleTopLevelDecl( clang::DeclGroupRef d) 34 | { 35 | static int count = 0; 36 | clang::DeclGroupRef::iterator it; 37 | for( it = d.begin(); it != d.end(); it++) 38 | { 39 | count++; 40 | clang::VarDecl *vd = llvm::dyn_cast(*it); 41 | if(!vd) 42 | { 43 | continue; 44 | } 45 | if( vd->isFileVarDecl() && !vd->hasExternalStorage() ) 46 | { 47 | std::cerr << "Read top-level variable decl: '"; 48 | std::cerr << vd->getDeclName().getAsString() ; 49 | std::cerr << std::endl; 50 | } 51 | } 52 | return true; 53 | } 54 | }; 55 | 56 | /****************************************************************************** 57 | * 58 | *****************************************************************************/ 59 | class MyFactory 60 | { 61 | public: 62 | std::unique_ptr newASTConsumer() { 63 | return llvm::make_unique(); 64 | } 65 | 66 | }; 67 | 68 | } // Namespace tooling 69 | 70 | /****************************************************************************** 71 | * 72 | *****************************************************************************/ 73 | int main(int argc, const char **argv) 74 | { 75 | CommonOptionsParser OptionsParser(argc, argv, MyToolCategory); 76 | ClangTool Tool(OptionsParser.getCompilations(), 77 | OptionsParser.getSourcePathList()); 78 | tooling::MyFactory myFactory; 79 | std::unique_ptr factory = newFrontendActionFactory(&myFactory); 80 | Tool.run(factory.get()); 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /Win/CItutorial1/CItutorial1.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {DC76E290-9392-4824-8C15-65CBB721C2EA} 15 | CItutorial1 16 | 17 | 18 | 19 | Application 20 | true 21 | MultiByte 22 | 23 | 24 | Application 25 | false 26 | true 27 | MultiByte 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | Level3 44 | Disabled 45 | $(LLVMIncludes);%(AdditionalIncludeDirectories) 46 | 47 | 48 | true 49 | $(LLVMLibsDirs);%(AdditionalLibraryDirectories) 50 | $(LLVMLibs);%(AdditionalDependencies) 51 | 52 | 53 | 54 | 55 | Level3 56 | MaxSpeed 57 | true 58 | true 59 | 60 | 61 | true 62 | true 63 | true 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Win/CItutorial2/CItutorial2.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {4FBB3914-2638-4922-AFAF-C13D70D58EA8} 15 | CItutorial2 16 | 17 | 18 | 19 | Application 20 | true 21 | MultiByte 22 | 23 | 24 | Application 25 | false 26 | true 27 | MultiByte 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | Level3 44 | Disabled 45 | $(LLVMIncludes);%(AdditionalIncludeDirectories) 46 | 47 | 48 | true 49 | $(LLVMLibsDirs);%(AdditionalLibraryDirectories) 50 | $(LLVMLibs);%(AdditionalDependencies) 51 | 52 | 53 | 54 | 55 | Level3 56 | MaxSpeed 57 | true 58 | true 59 | 60 | 61 | true 62 | true 63 | true 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Win/CItutorial3/CItutorial3.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {ACE80EE9-F690-4F05-A070-CAF4394C6A8B} 15 | CItutorial3 16 | 17 | 18 | 19 | Application 20 | true 21 | MultiByte 22 | 23 | 24 | Application 25 | false 26 | true 27 | MultiByte 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | Level3 44 | Disabled 45 | $(LLVMIncludes);%(AdditionalIncludeDirectories) 46 | 47 | 48 | true 49 | $(LLVMLibsDirs);%(AdditionalLibraryDirectories) 50 | $(LLVMLibs);%(AdditionalDependencies) 51 | 52 | 53 | 54 | 55 | Level3 56 | MaxSpeed 57 | true 58 | true 59 | 60 | 61 | true 62 | true 63 | true 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Win/CItutorial4/CItutorial4.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {9F0282CE-4917-40DD-AB0F-1B9D10B6D2E2} 15 | CItutorial4 16 | 17 | 18 | 19 | Application 20 | true 21 | MultiByte 22 | 23 | 24 | Application 25 | false 26 | true 27 | MultiByte 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | Level3 44 | Disabled 45 | $(LLVMIncludes);%(AdditionalIncludeDirectories) 46 | 47 | 48 | true 49 | $(LLVMLibsDirs);%(AdditionalLibraryDirectories) 50 | $(LLVMLibs);%(AdditionalDependencies) 51 | 52 | 53 | 54 | 55 | Level3 56 | MaxSpeed 57 | true 58 | true 59 | 60 | 61 | true 62 | true 63 | true 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Win/CItutorial6/CItutorial6.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {D58115B0-2851-42AF-A2C6-70EA1E2B4C10} 15 | CItutorial6 16 | 17 | 18 | 19 | Application 20 | true 21 | MultiByte 22 | 23 | 24 | Application 25 | false 26 | true 27 | MultiByte 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | Level3 44 | Disabled 45 | $(LLVMIncludes);%(AdditionalIncludeDirectories) 46 | 47 | 48 | true 49 | $(LLVMLibsDirs);%(AdditionalLibraryDirectories) 50 | $(LLVMLibs);%(AdditionalDependencies) 51 | 52 | 53 | 54 | 55 | Level3 56 | MaxSpeed 57 | true 58 | true 59 | 60 | 61 | true 62 | true 63 | true 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Win/ClangTutorial.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tutorial1", "tutorial1\tutorial1.vcxproj", "{B8628CFE-F3B2-4D1A-8ED4-0585D3102F8D}" 5 | EndProject 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tutorial2", "tutorial2\tutorial2.vcxproj", "{B652C205-C96C-4283-8461-D9E9B34DBDDA}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tutorial3", "tutorial3\tutorial3.vcxproj", "{D85877DE-3419-4FD8-9566-68E2A01DA8AD}" 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tutorial4", "tutorial4\tutorial4.vcxproj", "{A10B9C0B-C941-4295-A423-AEA977DE98B7}" 11 | EndProject 12 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tutorial6", "tutorial6\tutorial6.vcxproj", "{636C2E45-AD5A-4578-8386-685BCEFD918E}" 13 | EndProject 14 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SharedBuild", "SharedBuild\SharedBuild.vcxproj", "{4C3CD3F2-B881-4F77-831B-723D09D2DD39}" 15 | EndProject 16 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CItutorial1", "CItutorial1\CItutorial1.vcxproj", "{DC76E290-9392-4824-8C15-65CBB721C2EA}" 17 | EndProject 18 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CItutorial2", "CItutorial2\CItutorial2.vcxproj", "{4FBB3914-2638-4922-AFAF-C13D70D58EA8}" 19 | EndProject 20 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CItutorial3", "CItutorial3\CItutorial3.vcxproj", "{ACE80EE9-F690-4F05-A070-CAF4394C6A8B}" 21 | EndProject 22 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CItutorial4", "CItutorial4\CItutorial4.vcxproj", "{9F0282CE-4917-40DD-AB0F-1B9D10B6D2E2}" 23 | EndProject 24 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CItutorial6", "CItutorial6\CItutorial6.vcxproj", "{D58115B0-2851-42AF-A2C6-70EA1E2B4C10}" 25 | EndProject 26 | Global 27 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 28 | Debug|Win32 = Debug|Win32 29 | Release|Win32 = Release|Win32 30 | EndGlobalSection 31 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 32 | {B8628CFE-F3B2-4D1A-8ED4-0585D3102F8D}.Debug|Win32.ActiveCfg = Debug|Win32 33 | {B8628CFE-F3B2-4D1A-8ED4-0585D3102F8D}.Debug|Win32.Build.0 = Debug|Win32 34 | {B8628CFE-F3B2-4D1A-8ED4-0585D3102F8D}.Release|Win32.ActiveCfg = Release|Win32 35 | {B8628CFE-F3B2-4D1A-8ED4-0585D3102F8D}.Release|Win32.Build.0 = Release|Win32 36 | {B652C205-C96C-4283-8461-D9E9B34DBDDA}.Debug|Win32.ActiveCfg = Debug|Win32 37 | {B652C205-C96C-4283-8461-D9E9B34DBDDA}.Debug|Win32.Build.0 = Debug|Win32 38 | {B652C205-C96C-4283-8461-D9E9B34DBDDA}.Release|Win32.ActiveCfg = Release|Win32 39 | {B652C205-C96C-4283-8461-D9E9B34DBDDA}.Release|Win32.Build.0 = Release|Win32 40 | {D85877DE-3419-4FD8-9566-68E2A01DA8AD}.Debug|Win32.ActiveCfg = Debug|Win32 41 | {D85877DE-3419-4FD8-9566-68E2A01DA8AD}.Debug|Win32.Build.0 = Debug|Win32 42 | {D85877DE-3419-4FD8-9566-68E2A01DA8AD}.Release|Win32.ActiveCfg = Release|Win32 43 | {D85877DE-3419-4FD8-9566-68E2A01DA8AD}.Release|Win32.Build.0 = Release|Win32 44 | {A10B9C0B-C941-4295-A423-AEA977DE98B7}.Debug|Win32.ActiveCfg = Debug|Win32 45 | {A10B9C0B-C941-4295-A423-AEA977DE98B7}.Debug|Win32.Build.0 = Debug|Win32 46 | {A10B9C0B-C941-4295-A423-AEA977DE98B7}.Release|Win32.ActiveCfg = Release|Win32 47 | {A10B9C0B-C941-4295-A423-AEA977DE98B7}.Release|Win32.Build.0 = Release|Win32 48 | {636C2E45-AD5A-4578-8386-685BCEFD918E}.Debug|Win32.ActiveCfg = Debug|Win32 49 | {636C2E45-AD5A-4578-8386-685BCEFD918E}.Debug|Win32.Build.0 = Debug|Win32 50 | {636C2E45-AD5A-4578-8386-685BCEFD918E}.Release|Win32.ActiveCfg = Release|Win32 51 | {636C2E45-AD5A-4578-8386-685BCEFD918E}.Release|Win32.Build.0 = Release|Win32 52 | {4C3CD3F2-B881-4F77-831B-723D09D2DD39}.Debug|Win32.ActiveCfg = Debug|Win32 53 | {4C3CD3F2-B881-4F77-831B-723D09D2DD39}.Debug|Win32.Build.0 = Debug|Win32 54 | {4C3CD3F2-B881-4F77-831B-723D09D2DD39}.Release|Win32.ActiveCfg = Release|Win32 55 | {4C3CD3F2-B881-4F77-831B-723D09D2DD39}.Release|Win32.Build.0 = Release|Win32 56 | {DC76E290-9392-4824-8C15-65CBB721C2EA}.Debug|Win32.ActiveCfg = Debug|Win32 57 | {DC76E290-9392-4824-8C15-65CBB721C2EA}.Debug|Win32.Build.0 = Debug|Win32 58 | {DC76E290-9392-4824-8C15-65CBB721C2EA}.Release|Win32.ActiveCfg = Release|Win32 59 | {DC76E290-9392-4824-8C15-65CBB721C2EA}.Release|Win32.Build.0 = Release|Win32 60 | {4FBB3914-2638-4922-AFAF-C13D70D58EA8}.Debug|Win32.ActiveCfg = Debug|Win32 61 | {4FBB3914-2638-4922-AFAF-C13D70D58EA8}.Debug|Win32.Build.0 = Debug|Win32 62 | {4FBB3914-2638-4922-AFAF-C13D70D58EA8}.Release|Win32.ActiveCfg = Release|Win32 63 | {4FBB3914-2638-4922-AFAF-C13D70D58EA8}.Release|Win32.Build.0 = Release|Win32 64 | {ACE80EE9-F690-4F05-A070-CAF4394C6A8B}.Debug|Win32.ActiveCfg = Debug|Win32 65 | {ACE80EE9-F690-4F05-A070-CAF4394C6A8B}.Debug|Win32.Build.0 = Debug|Win32 66 | {ACE80EE9-F690-4F05-A070-CAF4394C6A8B}.Release|Win32.ActiveCfg = Release|Win32 67 | {ACE80EE9-F690-4F05-A070-CAF4394C6A8B}.Release|Win32.Build.0 = Release|Win32 68 | {9F0282CE-4917-40DD-AB0F-1B9D10B6D2E2}.Debug|Win32.ActiveCfg = Debug|Win32 69 | {9F0282CE-4917-40DD-AB0F-1B9D10B6D2E2}.Debug|Win32.Build.0 = Debug|Win32 70 | {9F0282CE-4917-40DD-AB0F-1B9D10B6D2E2}.Release|Win32.ActiveCfg = Release|Win32 71 | {9F0282CE-4917-40DD-AB0F-1B9D10B6D2E2}.Release|Win32.Build.0 = Release|Win32 72 | {D58115B0-2851-42AF-A2C6-70EA1E2B4C10}.Debug|Win32.ActiveCfg = Debug|Win32 73 | {D58115B0-2851-42AF-A2C6-70EA1E2B4C10}.Debug|Win32.Build.0 = Debug|Win32 74 | {D58115B0-2851-42AF-A2C6-70EA1E2B4C10}.Release|Win32.ActiveCfg = Release|Win32 75 | {D58115B0-2851-42AF-A2C6-70EA1E2B4C10}.Release|Win32.Build.0 = Release|Win32 76 | EndGlobalSection 77 | GlobalSection(SolutionProperties) = preSolution 78 | HideSolutionNode = FALSE 79 | EndGlobalSection 80 | EndGlobal 81 | -------------------------------------------------------------------------------- /Win/SharedBuild/SharedBuild.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | C:\Users\larry 6 | $(LocalUserDir)\Code\llvm 7 | $(LLVMSourceDir)\tools\clang 8 | $(LocalUserDir)\Code\llvm_build 9 | $(LLVMBuildDir)\tools\clang 10 | 11 | 12 | clangParse.lib;clangSerialization.lib;clangDriver.lib;clangIndex.lib;clangSema.lib;clangAnalysis.lib;clangAST.lib;clangFrontend.lib;clangEdit.lib;clangLex.lib;clangBasic.lib;LLVMSupport.lib;LLVMCore.lib;LLVMMC.lib; 13 | $(LLVMBuildDir)\lib\Debug; 14 | $(ClangSourceDir)\include;$(LLVMSourceDir)\include;$(LLVMBuildDir)\include;$(ClangBuildDir)\include; 15 | 16 | 17 | -------------------------------------------------------------------------------- /Win/SharedBuild/SharedBuild.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {4C3CD3F2-B881-4F77-831B-723D09D2DD39} 15 | SharedBuild 16 | SharedBuild 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | Designer 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Win/tutorial1/tutorial1.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {B8628CFE-F3B2-4D1A-8ED4-0585D3102F8D} 15 | tutorial1 16 | 17 | 18 | 19 | Application 20 | true 21 | MultiByte 22 | 23 | 24 | Application 25 | false 26 | true 27 | MultiByte 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | Level3 44 | Disabled 45 | $(LLVMIncludes);%(AdditionalIncludeDirectories) 46 | 47 | 48 | true 49 | $(LLVMLibsDirs);%(AdditionalLibraryDirectories) 50 | $(LLVMLibs);%(AdditionalDependencies) 51 | 52 | 53 | 54 | 55 | Level3 56 | MaxSpeed 57 | true 58 | true 59 | 60 | 61 | true 62 | true 63 | true 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /Win/tutorial2/tutorial2.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {B652C205-C96C-4283-8461-D9E9B34DBDDA} 15 | tutorial2 16 | 17 | 18 | 19 | Application 20 | true 21 | MultiByte 22 | 23 | 24 | Application 25 | false 26 | true 27 | MultiByte 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | Level3 44 | Disabled 45 | $(LLVMIncludes);%(AdditionalIncludeDirectories) 46 | 47 | 48 | true 49 | $(LLVMLibsDirs);%(AdditionalLibraryDirectories) 50 | $(LLVMLibs);%(AdditionalDependencies) 51 | 52 | 53 | 54 | 55 | Level3 56 | MaxSpeed 57 | true 58 | true 59 | 60 | 61 | true 62 | true 63 | true 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /Win/tutorial3/tutorial3.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {D85877DE-3419-4FD8-9566-68E2A01DA8AD} 15 | tutorial3 16 | 17 | 18 | 19 | Application 20 | true 21 | MultiByte 22 | 23 | 24 | Application 25 | false 26 | true 27 | MultiByte 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | Level3 44 | Disabled 45 | $(LLVMIncludes);%(AdditionalIncludeDirectories) 46 | 47 | 48 | true 49 | $(LLVMLibsDirs);%(AdditionalLibraryDirectories) 50 | $(LLVMLibs);%(AdditionalDependencies) 51 | 52 | 53 | 54 | 55 | Level3 56 | MaxSpeed 57 | true 58 | true 59 | 60 | 61 | true 62 | true 63 | true 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /Win/tutorial4/tutorial4.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {A10B9C0B-C941-4295-A423-AEA977DE98B7} 15 | tutorial4 16 | 17 | 18 | 19 | Application 20 | true 21 | MultiByte 22 | 23 | 24 | Application 25 | false 26 | true 27 | MultiByte 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | Level3 44 | Disabled 45 | $(LLVMIncludes);%(AdditionalIncludeDirectories) 46 | 47 | 48 | true 49 | $(LLVMLibsDirs);%(AdditionalLibraryDirectories) 50 | $(LLVMLibs);%(AdditionalDependencies) 51 | 52 | 53 | 54 | 55 | Level3 56 | MaxSpeed 57 | true 58 | true 59 | 60 | 61 | true 62 | true 63 | true 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /Win/tutorial6/tutorial6.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {636C2E45-AD5A-4578-8386-685BCEFD918E} 15 | tutorial6 16 | 17 | 18 | 19 | Application 20 | true 21 | MultiByte 22 | 23 | 24 | Application 25 | false 26 | true 27 | MultiByte 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | Level3 44 | Disabled 45 | $(LLVMIncludes);%(AdditionalIncludeDirectories) 46 | 47 | 48 | true 49 | $(LLVMLibsDirs);%(AdditionalLibraryDirectories) 50 | $(LLVMLibs);%(AdditionalDependencies) 51 | 52 | 53 | 54 | 55 | Level3 56 | MaxSpeed 57 | true 58 | true 59 | 60 | 61 | true 62 | true 63 | true 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /compile_commands.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "directory" : "/Users/lawrenceolson/Code/Clang-tutorial/", 4 | "command" : "clang -c -o input04.o input04.c", 5 | "file" : "input04.c" 6 | } 7 | ] 8 | -------------------------------------------------------------------------------- /input04.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern int bla; 4 | /*extern int bla2 = 4;*/ // invalid 5 | 6 | int a; 7 | int a = 3; 8 | 9 | int b = 4, c = 5; 10 | 11 | typedef unsigned int u32; 12 | typedef int (*funcpointertype)(int, int); 13 | typedef int functype(int, int); 14 | 15 | int (*funcp)(int, int); 16 | 17 | __typeof(funcp) fp2; 18 | funcpointertype fp3; 19 | 20 | functype f; 21 | __typeof(f) f2; 22 | 23 | int main() 24 | { 25 | int a = 4; 26 | 27 | int b = a; 28 | } 29 | 30 | /*int test() = main;*/ // illegal 31 | 32 | struct s {} t; 33 | struct x {}; 34 | -------------------------------------------------------------------------------- /invalidInputTest.c: -------------------------------------------------------------------------------- 1 | #de fine a 3 2 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | CXX := clang++ 2 | LLVMCOMPONENTS := cppbackend 3 | RTTIFLAG := -fno-rtti 4 | LLVMCONFIG := /Users/lawrenceolson/Code/build_llvm/Debug+Asserts/bin/llvm-config 5 | 6 | CXXFLAGS := -I$(shell $(LLVMCONFIG) --src-root)/tools/clang/include -I$(shell $(LLVMCONFIG) --obj-root)/tools/clang/include $(shell $(LLVMCONFIG) --cxxflags) $(RTTIFLAG) 7 | LLVMLDFLAGS := $(shell $(LLVMCONFIG) --ldflags --libs $(LLVMCOMPONENTS)) 8 | 9 | SOURCES = tutorial1.cpp \ 10 | tutorial2.cpp \ 11 | tutorial3.cpp \ 12 | tutorial4.cpp \ 13 | tutorial6.cpp \ 14 | CItutorial1.cpp \ 15 | CItutorial2.cpp \ 16 | CItutorial3.cpp \ 17 | CItutorial4.cpp \ 18 | CItutorial6.cpp \ 19 | CIBasicRecursiveASTVisitor.cpp \ 20 | CIrewriter.cpp \ 21 | ToolingTutorial.cpp \ 22 | CommentHandling.cpp 23 | 24 | OBJECTS = $(SOURCES:.cpp=.o) 25 | EXES = $(OBJECTS:.o=) 26 | CLANGLIBS = \ 27 | -lclangTooling\ 28 | -lclangFrontendTool\ 29 | -lclangFrontend\ 30 | -lclangDriver\ 31 | -lclangSerialization\ 32 | -lclangCodeGen\ 33 | -lclangParse\ 34 | -lclangSema\ 35 | -lclangStaticAnalyzerFrontend\ 36 | -lclangStaticAnalyzerCheckers\ 37 | -lclangStaticAnalyzerCore\ 38 | -lclangAnalysis\ 39 | -lclangARCMigrate\ 40 | -lclangRewrite\ 41 | -lclangRewriteFrontend\ 42 | -lclangEdit\ 43 | -lclangAST\ 44 | -lclangLex\ 45 | -lclangBasic\ 46 | $(shell $(LLVMCONFIG) --libs)\ 47 | $(shell $(LLVMCONFIG) --system-libs)\ 48 | -lcurses 49 | 50 | all: $(OBJECTS) $(EXES) 51 | 52 | %: %.o 53 | $(CXX) -o $@ $< $(CLANGLIBS) $(LLVMLDFLAGS) 54 | 55 | clean: 56 | -rm -f $(EXES) $(OBJECTS) *~ 57 | -------------------------------------------------------------------------------- /test.c: -------------------------------------------------------------------------------- 1 | //#include 2 | // This code is licensed under the New BSD license. 3 | // See LICENSE.txt for more details. 4 | 5 | int i = 4; 6 | extern int j; 7 | typedef int footype; 8 | 9 | int main() 10 | { 11 | typedef unsigned long bartype; 12 | printf("Hello World\n"); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /testInclude.c: -------------------------------------------------------------------------------- 1 | #include 2 | // This code is licensed under the New BSD license. 3 | // See LICENSE.txt for more details. 4 | 5 | int i = 4; 6 | extern int j; 7 | 8 | int main() 9 | { 10 | printf("Hello World\n"); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /test_rewriter.cpp: -------------------------------------------------------------------------------- 1 | int main() { 2 | bool a = true; 3 | bool b = false; 4 | 5 | if( (a && b) || ( b && a)) { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tutorial1.cpp: -------------------------------------------------------------------------------- 1 | // This code is licensed under the New BSD license. 2 | // See LICENSE.txt for more details. 3 | #include 4 | #include 5 | 6 | #include "llvm/Support/raw_ostream.h" 7 | #include "llvm/Support/Host.h" 8 | #include "llvm/ADT/IntrusiveRefCntPtr.h" 9 | 10 | #include "clang/Basic/DiagnosticOptions.h" 11 | #include "clang/Frontend/TextDiagnosticPrinter.h" 12 | 13 | #include "clang/Basic/LangOptions.h" 14 | #include "clang/Basic/FileSystemOptions.h" 15 | 16 | #include "clang/Basic/SourceManager.h" 17 | #include "clang/Lex/HeaderSearch.h" 18 | #include "clang/Basic/FileManager.h" 19 | 20 | #include "clang/Basic/TargetOptions.h" 21 | #include "clang/Basic/TargetInfo.h" 22 | 23 | #include "clang/Lex/Preprocessor.h" 24 | #include "clang/Frontend/CompilerInstance.h" 25 | 26 | 27 | int main() 28 | { 29 | clang::DiagnosticOptions diagnosticOptions; 30 | clang::TextDiagnosticPrinter *pTextDiagnosticPrinter = 31 | new clang::TextDiagnosticPrinter( 32 | llvm::outs(), 33 | &diagnosticOptions, 34 | true); 35 | llvm::IntrusiveRefCntPtr pDiagIDs; 36 | //clang::DiagnosticIDs diagIDs; 37 | 38 | clang::DiagnosticsEngine *pDiagnosticsEngine = 39 | new clang::DiagnosticsEngine(pDiagIDs, 40 | &diagnosticOptions, 41 | pTextDiagnosticPrinter); 42 | 43 | clang::LangOptions languageOptions; 44 | clang::FileSystemOptions fileSystemOptions; 45 | clang::FileManager fileManager(fileSystemOptions); 46 | clang::SourceManager sourceManager( 47 | *pDiagnosticsEngine, 48 | fileManager); 49 | 50 | 51 | std::shared_ptr targetOptions = std::make_shared(); 52 | // clang::TargetOptions targetOptions; 53 | targetOptions->Triple = llvm::sys::getDefaultTargetTriple(); 54 | 55 | clang::TargetInfo *pTargetInfo = 56 | clang::TargetInfo::CreateTargetInfo( 57 | *pDiagnosticsEngine, 58 | targetOptions); 59 | 60 | llvm::IntrusiveRefCntPtr hso; 61 | 62 | clang::HeaderSearch headerSearch(hso, 63 | sourceManager, 64 | *pDiagnosticsEngine, 65 | languageOptions, 66 | pTargetInfo); 67 | clang::CompilerInstance compInst; 68 | 69 | llvm::IntrusiveRefCntPtr pOpts; 70 | 71 | clang::Preprocessor preprocessor( 72 | pOpts, 73 | *pDiagnosticsEngine, 74 | languageOptions, 75 | sourceManager, 76 | headerSearch, 77 | compInst 78 | ); 79 | 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /tutorial2.cpp: -------------------------------------------------------------------------------- 1 | // This code is licensed under the New BSD license. 2 | // See LICENSE.txt for more details. 3 | #include 4 | #include 5 | 6 | #include "llvm/Support/raw_ostream.h" 7 | #include "llvm/Support/Host.h" 8 | 9 | #include "clang/Basic/DiagnosticOptions.h" 10 | #include "clang/Frontend/TextDiagnosticPrinter.h" 11 | 12 | #include "clang/Basic/LangOptions.h" 13 | #include "clang/Basic/FileSystemOptions.h" 14 | 15 | #include "clang/Basic/SourceManager.h" 16 | #include "clang/Lex/HeaderSearch.h" 17 | #include "clang/Basic/FileManager.h" 18 | 19 | #include "clang/Basic/TargetOptions.h" 20 | #include "clang/Basic/TargetInfo.h" 21 | 22 | #include "clang/Lex/Preprocessor.h" 23 | #include "clang/Frontend/CompilerInstance.h" 24 | 25 | 26 | int main() 27 | { 28 | clang::DiagnosticOptions diagnosticOptions; 29 | clang::TextDiagnosticPrinter *pTextDiagnosticPrinter = 30 | new clang::TextDiagnosticPrinter( 31 | llvm::outs(), 32 | &diagnosticOptions); 33 | llvm::IntrusiveRefCntPtr pDiagIDs; 34 | 35 | clang::DiagnosticsEngine *pDiagnosticsEngine = 36 | new clang::DiagnosticsEngine(pDiagIDs, 37 | &diagnosticOptions, 38 | pTextDiagnosticPrinter); 39 | 40 | clang::LangOptions languageOptions; 41 | clang::FileSystemOptions fileSystemOptions; 42 | clang::FileManager fileManager(fileSystemOptions); 43 | 44 | clang::SourceManager sourceManager( 45 | *pDiagnosticsEngine, 46 | fileManager); 47 | 48 | std::shared_ptr targetOptions = std::make_shared(); 49 | //clang::TargetOptions targetOptions; 50 | targetOptions->Triple = llvm::sys::getDefaultTargetTriple(); 51 | 52 | clang::TargetInfo *pTargetInfo = 53 | clang::TargetInfo::CreateTargetInfo( 54 | *pDiagnosticsEngine, 55 | targetOptions); 56 | 57 | llvm::IntrusiveRefCntPtr hso; 58 | clang::HeaderSearch headerSearch(hso, 59 | sourceManager, 60 | *pDiagnosticsEngine, 61 | languageOptions, 62 | pTargetInfo); 63 | clang::CompilerInstance compInst; 64 | 65 | llvm::IntrusiveRefCntPtr pOpts; 66 | 67 | clang::Preprocessor preprocessor( 68 | pOpts, 69 | *pDiagnosticsEngine, 70 | languageOptions, 71 | sourceManager, 72 | headerSearch, 73 | compInst 74 | ); 75 | 76 | //const clang::FileEntry file = sourceManager.getMainFileID(); 77 | const clang::FileEntry *pFile = fileManager.getFile("test.c"); 78 | sourceManager.setMainFileID( sourceManager.createFileID( pFile, clang::SourceLocation(), clang::SrcMgr::C_User)); 79 | preprocessor.EnterMainSourceFile(); 80 | pTextDiagnosticPrinter->BeginSourceFile(languageOptions, &preprocessor); 81 | 82 | clang::Token token; 83 | do { 84 | preprocessor.Lex(token); 85 | if( pDiagnosticsEngine->hasErrorOccurred()) 86 | { 87 | break; 88 | } 89 | preprocessor.DumpToken(token); 90 | std::cerr << std::endl; 91 | } while( token.isNot(clang::tok::eof)); 92 | pTextDiagnosticPrinter->EndSourceFile(); 93 | 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /tutorial3.cpp: -------------------------------------------------------------------------------- 1 | // This code is licensed under the New BSD license. 2 | // See LICENSE.txt for more details. 3 | #include 4 | 5 | #include "llvm/Support/raw_ostream.h" 6 | #include "llvm/Support/Host.h" 7 | 8 | #include "clang/Basic/DiagnosticOptions.h" 9 | #include "clang/Frontend/TextDiagnosticPrinter.h" 10 | 11 | #include "clang/Basic/LangOptions.h" 12 | #include "clang/Basic/FileSystemOptions.h" 13 | 14 | #include "clang/Basic/SourceManager.h" 15 | #include "clang/Lex/HeaderSearch.h" 16 | #include "clang/Basic/FileManager.h" 17 | 18 | #include "clang/Frontend/Utils.h" 19 | 20 | #include "clang/Basic/TargetOptions.h" 21 | #include "clang/Basic/TargetInfo.h" 22 | 23 | #include "clang/Lex/Preprocessor.h" 24 | #include "clang/Frontend/FrontendOptions.h" 25 | #include "clang/Frontend/CompilerInstance.h" 26 | 27 | 28 | int main() 29 | { 30 | clang::DiagnosticOptions diagnosticOptions; 31 | clang::TextDiagnosticPrinter *pTextDiagnosticPrinter = 32 | new clang::TextDiagnosticPrinter( 33 | llvm::outs(), 34 | &diagnosticOptions); 35 | llvm::IntrusiveRefCntPtr pDiagIDs; 36 | clang::DiagnosticsEngine *pDiagnosticsEngine = 37 | new clang::DiagnosticsEngine(pDiagIDs, 38 | &diagnosticOptions, 39 | pTextDiagnosticPrinter); 40 | 41 | clang::LangOptions languageOptions; 42 | clang::FileSystemOptions fileSystemOptions; 43 | clang::FileManager fileManager(fileSystemOptions); 44 | 45 | clang::SourceManager sourceManager( 46 | *pDiagnosticsEngine, 47 | fileManager); 48 | 49 | const std::shared_ptr targetOptions = std::make_shared(); 50 | targetOptions->Triple = llvm::sys::getDefaultTargetTriple(); 51 | 52 | clang::TargetInfo *pTargetInfo = 53 | clang::TargetInfo::CreateTargetInfo( 54 | *pDiagnosticsEngine, 55 | targetOptions); 56 | llvm::IntrusiveRefCntPtr hso(new clang::HeaderSearchOptions()); 57 | 58 | clang::HeaderSearch headerSearch(hso, 59 | sourceManager, 60 | *pDiagnosticsEngine, 61 | languageOptions, 62 | pTargetInfo); 63 | clang::CompilerInstance compInst; 64 | 65 | llvm::IntrusiveRefCntPtr pOpts(new clang::PreprocessorOptions); 66 | clang::Preprocessor preprocessor( 67 | pOpts, 68 | *pDiagnosticsEngine, 69 | languageOptions, 70 | sourceManager, 71 | headerSearch, 72 | compInst); 73 | 74 | preprocessor.Initialize(*pTargetInfo); 75 | 76 | // disable predefined Macros so that you only see the tokens from your 77 | // source file. Note, this has some nasty side-effects like also undefning 78 | // your archictecture and things like that. 79 | //preprocessorOptions.UsePredefines = false; 80 | 81 | clang::FrontendOptions frontendOptions; 82 | clang::InitializePreprocessor( 83 | preprocessor, 84 | *pOpts, 85 | frontendOptions); 86 | clang::ApplyHeaderSearchOptions( preprocessor.getHeaderSearchInfo(), 87 | compInst.getHeaderSearchOpts(), 88 | preprocessor.getLangOpts(), 89 | preprocessor.getTargetInfo().getTriple()); 90 | 91 | // Note: Changed the file from tutorial2. 92 | const clang::FileEntry *pFile = fileManager.getFile("testInclude.c"); 93 | sourceManager.setMainFileID( sourceManager.createFileID( pFile, clang::SourceLocation(), clang::SrcMgr::C_User)); 94 | preprocessor.EnterMainSourceFile(); 95 | pTextDiagnosticPrinter->BeginSourceFile(languageOptions, &preprocessor); 96 | 97 | clang::Token token; 98 | do { 99 | preprocessor.Lex(token); 100 | if( pDiagnosticsEngine->hasErrorOccurred()) 101 | { 102 | break; 103 | } 104 | preprocessor.DumpToken(token); 105 | std::cerr << std::endl; 106 | } while( token.isNot(clang::tok::eof)); 107 | pTextDiagnosticPrinter->EndSourceFile(); 108 | 109 | return 0; 110 | } 111 | -------------------------------------------------------------------------------- /tutorial4.cpp: -------------------------------------------------------------------------------- 1 | // This code is licensed under the New BSD license. 2 | // See LICENSE.txt for more details. 3 | #include 4 | 5 | #include "llvm/Support/raw_ostream.h" 6 | #include "llvm/Support/Host.h" 7 | 8 | #include "clang/Basic/DiagnosticOptions.h" 9 | #include "clang/Frontend/TextDiagnosticPrinter.h" 10 | 11 | #include "clang/Basic/LangOptions.h" 12 | #include "clang/Basic/FileSystemOptions.h" 13 | 14 | #include "clang/Basic/SourceManager.h" 15 | #include "clang/Lex/HeaderSearch.h" 16 | #include "clang/Basic/FileManager.h" 17 | 18 | #include "clang/Frontend/Utils.h" 19 | 20 | #include "clang/Basic/TargetOptions.h" 21 | #include "clang/Basic/TargetInfo.h" 22 | 23 | #include "clang/Lex/Preprocessor.h" 24 | #include "clang/Frontend/FrontendOptions.h" 25 | 26 | #include "clang/Basic/IdentifierTable.h" 27 | #include "clang/Basic/Builtins.h" 28 | 29 | #include "clang/AST/ASTContext.h" 30 | #include "clang/AST/ASTConsumer.h" 31 | #include "clang/Sema/Sema.h" 32 | 33 | #include "clang/Parse/ParseAST.h" 34 | #include "clang/Parse/Parser.h" 35 | #include "clang/Frontend/CompilerInstance.h" 36 | 37 | int main() 38 | { 39 | clang::DiagnosticOptions diagnosticOptions; 40 | clang::TextDiagnosticPrinter *pTextDiagnosticPrinter = 41 | new clang::TextDiagnosticPrinter( 42 | llvm::outs(), 43 | &diagnosticOptions); 44 | llvm::IntrusiveRefCntPtr pDiagIDs; 45 | clang::DiagnosticsEngine *pDiagnosticsEngine = 46 | new clang::DiagnosticsEngine(pDiagIDs, 47 | &diagnosticOptions, 48 | pTextDiagnosticPrinter); 49 | 50 | clang::LangOptions languageOptions; 51 | clang::FileSystemOptions fileSystemOptions; 52 | clang::FileManager fileManager(fileSystemOptions); 53 | 54 | clang::SourceManager sourceManager( 55 | *pDiagnosticsEngine, 56 | fileManager); 57 | 58 | llvm::IntrusiveRefCntPtr headerSearchOptions(new clang::HeaderSearchOptions()); 59 | // -- Platform Specific Code lives here 60 | // This depends on A) that you're running linux and 61 | // B) that you have the same GCC LIBs installed that 62 | // I do. 63 | // Search through Clang itself for something like this, 64 | // go on, you won't find it. The reason why is Clang 65 | // has its own versions of std* which are installed under 66 | // /usr/local/lib/clang//include/ 67 | // See somewhere around Driver.cpp:77 to see Clang adding 68 | // its version of the headers to its include path. 69 | headerSearchOptions->AddPath("/usr/include/linux", 70 | clang::frontend::Angled, 71 | false, 72 | false); 73 | headerSearchOptions->AddPath("/usr/include/c++/4.4/tr1", 74 | clang::frontend::Angled, 75 | false, 76 | false); 77 | headerSearchOptions->AddPath("/usr/include/c++/4.4", 78 | clang::frontend::Angled, 79 | false, 80 | false); 81 | // -- End of Platform Specific Code 82 | 83 | const std::shared_ptr targetOptions = std::make_shared(); 84 | targetOptions->Triple = llvm::sys::getDefaultTargetTriple(); 85 | 86 | clang::TargetInfo *pTargetInfo = 87 | clang::TargetInfo::CreateTargetInfo( 88 | *pDiagnosticsEngine, 89 | targetOptions); 90 | 91 | clang::HeaderSearch headerSearch(headerSearchOptions, 92 | sourceManager, 93 | *pDiagnosticsEngine, 94 | languageOptions, 95 | pTargetInfo); 96 | clang::CompilerInstance compInst; 97 | 98 | llvm::IntrusiveRefCntPtr pOpts(new clang::PreprocessorOptions()); 99 | clang::Preprocessor preprocessor( 100 | pOpts, 101 | *pDiagnosticsEngine, 102 | languageOptions, 103 | sourceManager, 104 | headerSearch, 105 | compInst); 106 | preprocessor.Initialize(*pTargetInfo); 107 | 108 | clang::FrontendOptions frontendOptions; 109 | clang::InitializePreprocessor( 110 | preprocessor, 111 | *pOpts, 112 | frontendOptions); 113 | 114 | const clang::FileEntry *pFile = fileManager.getFile( 115 | "test.c"); 116 | 117 | sourceManager.setMainFileID( sourceManager.createFileID( pFile, clang::SourceLocation(), clang::SrcMgr::C_User)); 118 | const clang::TargetInfo &targetInfo = *pTargetInfo; 119 | 120 | clang::IdentifierTable identifierTable(languageOptions); 121 | clang::SelectorTable selectorTable; 122 | 123 | clang::Builtin::Context builtinContext; 124 | builtinContext.InitializeTarget(targetInfo); 125 | clang::ASTContext astContext( 126 | languageOptions, 127 | sourceManager, 128 | identifierTable, 129 | selectorTable, 130 | builtinContext); 131 | astContext.InitBuiltinTypes(*pTargetInfo); 132 | clang::ASTConsumer astConsumer; 133 | 134 | clang::Sema sema( 135 | preprocessor, 136 | astContext, 137 | astConsumer); 138 | 139 | pTextDiagnosticPrinter->BeginSourceFile(languageOptions, &preprocessor); 140 | clang::ParseAST(preprocessor, &astConsumer, astContext); 141 | pTextDiagnosticPrinter->EndSourceFile(); 142 | identifierTable.PrintStats(); 143 | 144 | return 0; 145 | } 146 | -------------------------------------------------------------------------------- /tutorial6.cpp: -------------------------------------------------------------------------------- 1 | // This code is licensed under the New BSD license. 2 | // See LICENSE.txt for more details. 3 | #include 4 | 5 | #include "llvm/Support/raw_ostream.h" 6 | #include "llvm/Support/Host.h" 7 | #include "llvm/Support/Casting.h" 8 | 9 | #include "clang/Basic/DiagnosticOptions.h" 10 | #include "clang/Frontend/TextDiagnosticPrinter.h" 11 | 12 | #include "clang/Basic/LangOptions.h" 13 | #include "clang/Basic/FileSystemOptions.h" 14 | 15 | #include "clang/Basic/SourceManager.h" 16 | #include "clang/Lex/HeaderSearch.h" 17 | #include "clang/Basic/FileManager.h" 18 | 19 | #include "clang/Frontend/Utils.h" 20 | 21 | #include "clang/Basic/TargetOptions.h" 22 | #include "clang/Basic/TargetInfo.h" 23 | 24 | #include "clang/Lex/Preprocessor.h" 25 | #include "clang/Frontend/FrontendOptions.h" 26 | 27 | #include "clang/Basic/IdentifierTable.h" 28 | #include "clang/Basic/Builtins.h" 29 | 30 | #include "clang/AST/ASTContext.h" 31 | #include "clang/AST/ASTConsumer.h" 32 | #include "clang/Sema/Sema.h" 33 | #include "clang/AST/DeclBase.h" 34 | #include "clang/AST/Type.h" 35 | #include "clang/AST/Decl.h" 36 | #include "clang/Sema/Lookup.h" 37 | #include "clang/Sema/Ownership.h" 38 | #include "clang/AST/DeclGroup.h" 39 | 40 | #include "clang/Parse/Parser.h" 41 | 42 | #include "clang/Parse/ParseAST.h" 43 | #include "clang/Frontend/CompilerInstance.h" 44 | 45 | class MyASTConsumer : public clang::ASTConsumer 46 | { 47 | public: 48 | MyASTConsumer() : clang::ASTConsumer() { } 49 | virtual ~MyASTConsumer() { } 50 | 51 | virtual bool HandleTopLevelDecl( clang::DeclGroupRef d) 52 | { 53 | static int count = 0; 54 | clang::DeclGroupRef::iterator it; 55 | for( it = d.begin(); it != d.end(); it++) 56 | { 57 | count++; 58 | clang::VarDecl *vd = llvm::dyn_cast(*it); 59 | if(!vd) 60 | { 61 | continue; 62 | } 63 | if( vd->isFileVarDecl() && !vd->hasExternalStorage() ) 64 | { 65 | std::cerr << "Read top-level variable decl: '"; 66 | std::cerr << vd->getDeclName().getAsString() ; 67 | std::cerr << std::endl; 68 | } 69 | } 70 | return true; 71 | } 72 | }; 73 | 74 | int main() 75 | { 76 | clang::DiagnosticOptions diagnosticOptions; 77 | clang::TextDiagnosticPrinter *pTextDiagnosticPrinter = 78 | new clang::TextDiagnosticPrinter( 79 | llvm::outs(), 80 | &diagnosticOptions); 81 | llvm::IntrusiveRefCntPtr pDiagIDs; 82 | clang::DiagnosticsEngine *pDiagnosticsEngine = 83 | new clang::DiagnosticsEngine(pDiagIDs, 84 | &diagnosticOptions, 85 | pTextDiagnosticPrinter); 86 | 87 | clang::LangOptions languageOptions; 88 | clang::FileSystemOptions fileSystemOptions; 89 | clang::FileManager fileManager(fileSystemOptions); 90 | 91 | clang::SourceManager sourceManager( 92 | *pDiagnosticsEngine, 93 | fileManager); 94 | 95 | llvm::IntrusiveRefCntPtr headerSearchOptions(new clang::HeaderSearchOptions()); 96 | // -- Platform Specific Code lives here 97 | // This depends on A) that you're running linux and 98 | // B) that you have the same GCC LIBs installed that 99 | // I do. 100 | // Search through Clang itself for something like this, 101 | // go on, you won't find it. The reason why is Clang 102 | // has its own versions of std* which are installed under 103 | // /usr/local/lib/clang//include/ 104 | // See somewhere around Driver.cpp:77 to see Clang adding 105 | // its version of the headers to its include path. 106 | headerSearchOptions->AddPath("/usr/include/linux", 107 | clang::frontend::Angled, 108 | false, 109 | false); 110 | headerSearchOptions->AddPath("/usr/include/c++/4.4/tr1", 111 | clang::frontend::Angled, 112 | false, 113 | false); 114 | headerSearchOptions->AddPath("/usr/include/c++/4.4", 115 | clang::frontend::Angled, 116 | false, 117 | false); 118 | // -- End of Platform Specific Code 119 | 120 | const std::shared_ptr targetOptions = std::make_shared(); 121 | targetOptions->Triple = llvm::sys::getDefaultTargetTriple(); 122 | 123 | clang::TargetInfo *pTargetInfo = 124 | clang::TargetInfo::CreateTargetInfo( 125 | *pDiagnosticsEngine, 126 | targetOptions); 127 | 128 | clang::HeaderSearch headerSearch(headerSearchOptions, 129 | sourceManager, 130 | *pDiagnosticsEngine, 131 | languageOptions, 132 | pTargetInfo); 133 | clang::CompilerInstance compInst; 134 | 135 | llvm::IntrusiveRefCntPtr pOpts( new clang::PreprocessorOptions()); 136 | clang::Preprocessor preprocessor( 137 | pOpts, 138 | *pDiagnosticsEngine, 139 | languageOptions, 140 | sourceManager, 141 | headerSearch, 142 | compInst); 143 | preprocessor.Initialize(*pTargetInfo); 144 | 145 | clang::FrontendOptions frontendOptions; 146 | clang::InitializePreprocessor( 147 | preprocessor, 148 | *pOpts, 149 | frontendOptions); 150 | clang::ApplyHeaderSearchOptions( preprocessor.getHeaderSearchInfo(), 151 | compInst.getHeaderSearchOpts(), 152 | preprocessor.getLangOpts(), 153 | preprocessor.getTargetInfo().getTriple()); 154 | 155 | 156 | const clang::FileEntry *pFile = fileManager.getFile( 157 | "input04.c"); 158 | sourceManager.setMainFileID( sourceManager.createFileID( pFile, clang::SourceLocation(), clang::SrcMgr::C_User)); 159 | 160 | const clang::TargetInfo &targetInfo = *pTargetInfo; 161 | 162 | clang::IdentifierTable identifierTable(languageOptions); 163 | clang::SelectorTable selectorTable; 164 | 165 | clang::Builtin::Context builtinContext; 166 | builtinContext.InitializeTarget(targetInfo); 167 | clang::ASTContext astContext( 168 | languageOptions, 169 | sourceManager, 170 | identifierTable, 171 | selectorTable, 172 | builtinContext); 173 | astContext.InitBuiltinTypes(*pTargetInfo); 174 | 175 | MyASTConsumer astConsumer; 176 | 177 | clang::Sema sema( 178 | preprocessor, 179 | astContext, 180 | astConsumer); 181 | 182 | pTextDiagnosticPrinter->BeginSourceFile(languageOptions, &preprocessor); 183 | clang::ParseAST(preprocessor, &astConsumer, astContext); 184 | pTextDiagnosticPrinter->EndSourceFile(); 185 | return 0; 186 | } 187 | --------------------------------------------------------------------------------