Index: include/clang/AST/ASTConsumer.h =================================================================== --- include/clang/AST/ASTConsumer.h +++ include/clang/AST/ASTConsumer.h @@ -14,6 +14,8 @@ #ifndef LLVM_CLANG_AST_ASTCONSUMER_H #define LLVM_CLANG_AST_ASTCONSUMER_H +#include + namespace clang { class ASTContext; class CXXMethodDecl; @@ -27,6 +29,8 @@ class VarDecl; class FunctionDecl; class ImportDecl; + class PPCallbacks; + class Preprocessor; /// ASTConsumer - This is an abstract interface that should be implemented by /// clients that read ASTs. This abstraction layer allows the client to be @@ -139,6 +143,12 @@ /// body may be parsed anyway if it is needed (for instance, if it contains /// the code completion point or is constexpr). virtual bool shouldSkipFunctionBody(Decl *D) { return true; } + + /// If the consumer is interested in notifications from Preprocessor, + /// for example: notifications on macro definitions, etc., it should return + /// a pointer to a PPCallbacks here. + /// The caller takes ownership on the returned pointer. + virtual std::unique_ptr CreatePreprocessorCallbacks(Preprocessor &PP); }; } // end namespace clang. Index: lib/AST/ASTConsumer.cpp =================================================================== --- lib/AST/ASTConsumer.cpp +++ lib/AST/ASTConsumer.cpp @@ -14,6 +14,7 @@ #include "clang/AST/ASTConsumer.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclGroup.h" +#include "clang/Lex/PPCallbacks.h" using namespace clang; bool ASTConsumer::HandleTopLevelDecl(DeclGroupRef D) { @@ -29,3 +30,9 @@ void ASTConsumer::HandleImplicitImportDecl(ImportDecl *D) { HandleTopLevelDecl(DeclGroupRef(D)); } + +std::unique_ptr + +ASTConsumer::CreatePreprocessorCallbacks(Preprocessor &PP) { + return nullptr; +} Index: lib/CodeGen/CGDebugInfo.h =================================================================== --- lib/CodeGen/CGDebugInfo.h +++ lib/CodeGen/CGDebugInfo.h @@ -386,6 +386,16 @@ void completeTemplateDefinition(const ClassTemplateSpecializationDecl &SD); + /// Get Macro debug info. + llvm::DIMacro *CreateMacro(llvm::DIMacroFile *Parent, unsigned MType, + SourceLocation LineLoc, StringRef Name, + StringRef Value); + + /// Get Macro File debug info. + llvm::DIMacroFile *CreateMacroFile(llvm::DIMacroFile *Parent, + SourceLocation LineLoc, + SourceLocation FileLoc); + private: /// Emit call to llvm.dbg.declare for a variable declaration. void EmitDeclare(const VarDecl *decl, llvm::Value *AI, Index: lib/CodeGen/CGDebugInfo.cpp =================================================================== --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -2264,6 +2264,22 @@ FullName); } +llvm::DIMacro *CGDebugInfo::CreateMacro(llvm::DIMacroFile *Parent, + unsigned MType, SourceLocation LineLoc, + StringRef Name, StringRef Value) { + unsigned Line = LineLoc.isInvalid() ? 0 : getLineNumber(LineLoc); + return DBuilder.createMacro(Parent, Line, MType, Name, Value); +} + +llvm::DIMacroFile *CGDebugInfo::CreateMacroFile(llvm::DIMacroFile *Parent, + SourceLocation LineLoc, + SourceLocation FileLoc) { + llvm::DIFile *FName = getOrCreateFile(FileLoc); + unsigned Line = LineLoc.isInvalid() ? 0 : getLineNumber(LineLoc); + return DBuilder.createMacroFile(Parent, Line, FName, + llvm::DIMacroNodeArray()); +} + static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C) { Qualifiers Quals; do { Index: lib/CodeGen/CMakeLists.txt =================================================================== --- lib/CodeGen/CMakeLists.txt +++ lib/CodeGen/CMakeLists.txt @@ -73,6 +73,7 @@ CodeGenTypes.cpp CoverageMappingGen.cpp ItaniumCXXABI.cpp + MacroPPCallbacks.cpp MicrosoftCXXABI.cpp ModuleBuilder.cpp ObjectFilePCHContainerOperations.cpp Index: lib/CodeGen/CodeGenAction.cpp =================================================================== --- lib/CodeGen/CodeGenAction.cpp +++ lib/CodeGen/CodeGenAction.cpp @@ -222,6 +222,11 @@ Gen->HandleVTable(RD); } + std::unique_ptr + CreatePreprocessorCallbacks(Preprocessor &PP) override { + return Gen->CreatePreprocessorCallbacks(PP); + } + static void InlineAsmDiagHandler(const llvm::SMDiagnostic &SM,void *Context, unsigned LocCookie) { SourceLocation Loc = SourceLocation::getFromRawEncoding(LocCookie); Index: lib/CodeGen/CodeGenModule.h =================================================================== --- lib/CodeGen/CodeGenModule.h +++ lib/CodeGen/CodeGenModule.h @@ -77,6 +77,8 @@ class CXXDestructorDecl; class Module; class CoverageSourceInfo; +class Preprocessor; +class PPCallbacks; namespace CodeGen { @@ -591,6 +593,8 @@ CGDebugInfo *getModuleDebugInfo() { return DebugInfo.get(); } + std::unique_ptr createPreprocessorCallbacks(Preprocessor &PP); + llvm::MDNode *getNoObjCARCExceptionsMetadata() { if (!NoObjCARCExceptionsMetadata) NoObjCARCExceptionsMetadata = llvm::MDNode::get(getLLVMContext(), None); Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -25,6 +25,7 @@ #include "CodeGenPGO.h" #include "CodeGenTBAA.h" #include "CoverageMappingGen.h" +#include "MacroPPCallbacks.h" #include "TargetInfo.h" #include "clang/AST/ASTContext.h" #include "clang/AST/CharUnits.h" @@ -204,6 +205,16 @@ CUDARuntime.reset(CreateNVCUDARuntime(*this)); } +std::unique_ptr +CodeGenModule::createPreprocessorCallbacks(Preprocessor &PP) { + // Enable generating macro debug info only in FullDebugInfo mode. + if (CodeGenOpts.getDebugInfo() < codegenoptions::FullDebugInfo || + !getModuleDebugInfo()) + return nullptr; + + return llvm::make_unique(*getModuleDebugInfo(), PP); +} + void CodeGenModule::addReplacement(StringRef Name, llvm::Constant *C) { Replacements[Name] = C; } Index: lib/CodeGen/ModuleBuilder.cpp =================================================================== --- lib/CodeGen/ModuleBuilder.cpp +++ lib/CodeGen/ModuleBuilder.cpp @@ -20,6 +20,7 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/TargetInfo.h" #include "clang/Frontend/CodeGenOptions.h" +#include "clang/Lex/PPCallbacks.h" #include "llvm/ADT/StringRef.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/LLVMContext.h" @@ -130,6 +131,11 @@ Builder->AppendLinkerOptions(Opt); } + std::unique_ptr + CreatePreprocessorCallbacks(Preprocessor &PP) override { + return Builder->createPreprocessorCallbacks(PP); + } + void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override { if (Diags.hasErrorOccurred()) return; Index: lib/Parse/ParseAST.cpp =================================================================== --- lib/Parse/ParseAST.cpp +++ lib/Parse/ParseAST.cpp @@ -127,6 +127,12 @@ new Parser(S.getPreprocessor(), S, SkipFunctionBodies)); Parser &P = *ParseOP.get(); + std::unique_ptr Callbacks = + Consumer->CreatePreprocessorCallbacks(S.getPreprocessor()); + if (Callbacks) { + S.getPreprocessor().addPPCallbacks(std::move(Callbacks)); + } + llvm::CrashRecoveryContextCleanupRegistrar CleanupPrettyStack(llvm::SavePrettyStackState()); PrettyStackTraceParserEntry CrashInfo(P);