Author: nico Date: Wed Mar 2 11:28:48 2016 New Revision: 262493 URL: http://llvm.org/viewvc/llvm-project?rev=262493&view=rev Log: Serialize `#pragma comment`.
`#pragma comment` was handled by Sema calling a function on ASTConsumer, and CodeGen then implementing this function and writing things to its output. Instead, introduce a PragmaCommentDecl AST node and hang one off the TranslationUnitDecl for every `#pragma comment` line, and then use the regular serialization machinery. (Since PragmaCommentDecl has codegen relevance, it's eagerly deserialized.) http://reviews.llvm.org/D17799 Added: cfe/trunk/include/clang/Basic/PragmaKinds.h cfe/trunk/test/PCH/pragma-comment.c Modified: cfe/trunk/include/clang/AST/ASTConsumer.h cfe/trunk/include/clang/AST/Decl.h cfe/trunk/include/clang/AST/RecursiveASTVisitor.h cfe/trunk/include/clang/Basic/DeclNodes.td cfe/trunk/include/clang/Frontend/MultiplexConsumer.h cfe/trunk/include/clang/Sema/Sema.h cfe/trunk/include/clang/Serialization/ASTBitCodes.h cfe/trunk/lib/AST/ASTContext.cpp cfe/trunk/lib/AST/ASTDumper.cpp cfe/trunk/lib/AST/Decl.cpp cfe/trunk/lib/AST/DeclBase.cpp cfe/trunk/lib/CodeGen/CGDecl.cpp cfe/trunk/lib/CodeGen/CodeGenAction.cpp cfe/trunk/lib/CodeGen/CodeGenModule.cpp cfe/trunk/lib/CodeGen/ModuleBuilder.cpp cfe/trunk/lib/Frontend/MultiplexConsumer.cpp cfe/trunk/lib/Parse/ParsePragma.cpp cfe/trunk/lib/Sema/SemaAttr.cpp cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp cfe/trunk/lib/Serialization/ASTCommon.cpp cfe/trunk/lib/Serialization/ASTReaderDecl.cpp cfe/trunk/lib/Serialization/ASTWriterDecl.cpp cfe/trunk/tools/libclang/CIndex.cpp Modified: cfe/trunk/include/clang/AST/ASTConsumer.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTConsumer.h?rev=262493&r1=262492&r2=262493&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/ASTConsumer.h (original) +++ cfe/trunk/include/clang/AST/ASTConsumer.h Wed Mar 2 11:28:48 2016 @@ -94,22 +94,12 @@ public: /// The default implementation passes it to HandleTopLevelDecl. virtual void HandleImplicitImportDecl(ImportDecl *D); - /// \brief Handle a pragma or command line flag that appends to Linker - /// Options. This exists to support Microsoft's - /// #pragma comment(linker, "/foo") and the frontend flag --linker-option=. - virtual void HandleLinkerOption(llvm::StringRef Opts) {} - /// \brief Handle a pragma that emits a mismatch identifier and value to the /// object file for the linker to work with. Currently, this only exists to /// support Microsoft's #pragma detect_mismatch. virtual void HandleDetectMismatch(llvm::StringRef Name, llvm::StringRef Value) {} - /// \brief Handle a dependent library created by a pragma in the source. - /// Currently this only exists to support Microsoft's - /// #pragma comment(lib, "/foo"). - virtual void HandleDependentLibrary(llvm::StringRef Lib) {} - /// CompleteTentativeDefinition - Callback invoked at the end of a translation /// unit to notify the consumer that the given tentative definition should be /// completed. Modified: cfe/trunk/include/clang/AST/Decl.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=262493&r1=262492&r2=262493&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/Decl.h (original) +++ cfe/trunk/include/clang/AST/Decl.h Wed Mar 2 11:28:48 2016 @@ -23,6 +23,7 @@ #include "clang/Basic/Linkage.h" #include "clang/Basic/Module.h" #include "clang/Basic/OperatorKinds.h" +#include "clang/Basic/PragmaKinds.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/Compiler.h" @@ -103,6 +104,40 @@ public: } }; +/// \brief Represents a `#pragma comment` line. Always a child of +/// TranslationUnitDecl. +class PragmaCommentDecl final + : public Decl, + private llvm::TrailingObjects<PragmaCommentDecl, char> { + virtual void anchor(); + + PragmaMSCommentKind CommentKind; + + friend TrailingObjects; + friend class ASTDeclReader; + friend class ASTDeclWriter; + + PragmaCommentDecl(TranslationUnitDecl *TU, SourceLocation CommentLoc, + PragmaMSCommentKind CommentKind) + : Decl(PragmaComment, TU, CommentLoc), CommentKind(CommentKind) {} + +public: + static PragmaCommentDecl *Create(const ASTContext &C, TranslationUnitDecl *DC, + SourceLocation CommentLoc, + PragmaMSCommentKind CommentKind, + StringRef Arg); + static PragmaCommentDecl *CreateDeserialized(ASTContext &C, unsigned ID, + unsigned ArgSize); + + PragmaMSCommentKind getCommentKind() const { return CommentKind; } + + StringRef getArg() const { return getTrailingObjects<char>(); } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == PragmaComment; } +}; + /// \brief Declaration context for names declared as extern "C" in C++. This /// is neither the semantic nor lexical context for such declarations, but is /// used to check for conflicts with other extern "C" declarations. Example: Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=262493&r1=262492&r2=262493&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original) +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Wed Mar 2 11:28:48 2016 @@ -1359,6 +1359,8 @@ DEF_TRAVERSE_DECL( // D->getAnonymousNamespace(). }) +DEF_TRAVERSE_DECL(PragmaCommentDecl, {}) + DEF_TRAVERSE_DECL(ExternCContextDecl, {}) DEF_TRAVERSE_DECL(NamespaceAliasDecl, { Modified: cfe/trunk/include/clang/Basic/DeclNodes.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DeclNodes.td?rev=262493&r1=262492&r2=262493&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DeclNodes.td (original) +++ cfe/trunk/include/clang/Basic/DeclNodes.td Wed Mar 2 11:28:48 2016 @@ -11,6 +11,7 @@ class DDecl<Decl base, bit abstract = 0> class DeclContext { } def TranslationUnit : Decl, DeclContext; +def PragmaComment : Decl; def ExternCContext : Decl, DeclContext; def Named : Decl<1>; def Namespace : DDecl<Named>, DeclContext; Added: cfe/trunk/include/clang/Basic/PragmaKinds.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/PragmaKinds.h?rev=262493&view=auto ============================================================================== --- cfe/trunk/include/clang/Basic/PragmaKinds.h (added) +++ cfe/trunk/include/clang/Basic/PragmaKinds.h Wed Mar 2 11:28:48 2016 @@ -0,0 +1,26 @@ +//===--- PragmaKinds.h - #pragma comment() kinds ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_PRAGMA_KINDS_H +#define LLVM_CLANG_BASIC_PRAGMA_KINDS_H + +namespace clang { + +enum PragmaMSCommentKind { + PCK_Unknown, + PCK_Linker, // #pragma comment(linker, ...) + PCK_Lib, // #pragma comment(lib, ...) + PCK_Compiler, // #pragma comment(compiler, ...) + PCK_ExeStr, // #pragma comment(exestr, ...) + PCK_User // #pragma comment(user, ...) +}; + +} + +#endif Modified: cfe/trunk/include/clang/Frontend/MultiplexConsumer.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/MultiplexConsumer.h?rev=262493&r1=262492&r2=262493&view=diff ============================================================================== --- cfe/trunk/include/clang/Frontend/MultiplexConsumer.h (original) +++ cfe/trunk/include/clang/Frontend/MultiplexConsumer.h Wed Mar 2 11:28:48 2016 @@ -44,10 +44,8 @@ public: void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) override; void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override; void HandleImplicitImportDecl(ImportDecl *D) override; - void HandleLinkerOption(llvm::StringRef Opts) override; void HandleDetectMismatch(llvm::StringRef Name, llvm::StringRef Value) override; - void HandleDependentLibrary(llvm::StringRef Lib) override; void CompleteTentativeDefinition(VarDecl *D) override; void AssignInheritanceModel(CXXRecordDecl *RD) override; void HandleVTable(CXXRecordDecl *RD) override; Modified: cfe/trunk/include/clang/Sema/Sema.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=262493&r1=262492&r2=262493&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/Sema.h (original) +++ cfe/trunk/include/clang/Sema/Sema.h Wed Mar 2 11:28:48 2016 @@ -29,6 +29,7 @@ #include "clang/Basic/LangOptions.h" #include "clang/Basic/Module.h" #include "clang/Basic/OpenMPKinds.h" +#include "clang/Basic/PragmaKinds.h" #include "clang/Basic/Specifiers.h" #include "clang/Basic/TemplateKinds.h" #include "clang/Basic/TypeTraits.h" @@ -7615,15 +7616,6 @@ public: PMSST_ON // #pragms ms_struct on }; - enum PragmaMSCommentKind { - PCK_Unknown, - PCK_Linker, // #pragma comment(linker, ...) - PCK_Lib, // #pragma comment(lib, ...) - PCK_Compiler, // #pragma comment(compiler, ...) - PCK_ExeStr, // #pragma comment(exestr, ...) - PCK_User // #pragma comment(user, ...) - }; - /// ActOnPragmaPack - Called on well formed \#pragma pack(...). void ActOnPragmaPack(PragmaPackKind Kind, IdentifierInfo *Name, @@ -7637,7 +7629,8 @@ public: /// ActOnPragmaMSComment - Called on well formed /// \#pragma comment(kind, "arg"). - void ActOnPragmaMSComment(PragmaMSCommentKind Kind, StringRef Arg); + void ActOnPragmaMSComment(SourceLocation CommentLoc, PragmaMSCommentKind Kind, + StringRef Arg); /// ActOnPragmaMSPointersToMembers - called on well formed \#pragma /// pointers_to_members(representation method[, general purpose Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=262493&r1=262492&r2=262493&view=diff ============================================================================== --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original) +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Wed Mar 2 11:28:48 2016 @@ -1164,7 +1164,9 @@ namespace clang { /// \brief An ObjCTypeParamDecl record. DECL_OBJC_TYPE_PARAM, /// \brief An OMPCapturedExprDecl record. - DECL_OMP_CAPTUREDEXPR + DECL_OMP_CAPTUREDEXPR, + /// \brief A PragmaCommentDecl record. + DECL_PRAGMA_COMMENT }; /// \brief Record codes for each kind of statement or expression. Modified: cfe/trunk/lib/AST/ASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=262493&r1=262492&r2=262493&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTContext.cpp (original) +++ cfe/trunk/lib/AST/ASTContext.cpp Wed Mar 2 11:28:48 2016 @@ -8503,7 +8503,9 @@ bool ASTContext::DeclMustBeEmitted(const // We never need to emit an uninstantiated function template. if (FD->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate) return false; - } else if (isa<OMPThreadPrivateDecl>(D)) + } else if (isa<PragmaCommentDecl>(D)) + return true; + else if (isa<OMPThreadPrivateDecl>(D)) return true; else return false; Modified: cfe/trunk/lib/AST/ASTDumper.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDumper.cpp?rev=262493&r1=262492&r2=262493&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTDumper.cpp (original) +++ cfe/trunk/lib/AST/ASTDumper.cpp Wed Mar 2 11:28:48 2016 @@ -426,6 +426,7 @@ namespace { void VisitVarDecl(const VarDecl *D); void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D); void VisitImportDecl(const ImportDecl *D); + void VisitPragmaCommentDecl(const PragmaCommentDecl *D); // C++ Decls void VisitNamespaceDecl(const NamespaceDecl *D); @@ -1200,6 +1201,21 @@ void ASTDumper::VisitImportDecl(const Im OS << ' ' << D->getImportedModule()->getFullModuleName(); } +void ASTDumper::VisitPragmaCommentDecl(const PragmaCommentDecl *D) { + OS << ' '; + switch (D->getCommentKind()) { + case PCK_Unknown: llvm_unreachable("unexpected pragma comment kind"); + case PCK_Compiler: OS << "compiler"; break; + case PCK_ExeStr: OS << "exestr"; break; + case PCK_Lib: OS << "lib"; break; + case PCK_Linker: OS << "linker"; break; + case PCK_User: OS << "user"; break; + } + StringRef Arg = D->getArg(); + if (!Arg.empty()) + OS << " \"" << Arg << "\""; +} + //===----------------------------------------------------------------------===// // C++ Declarations //===----------------------------------------------------------------------===// Modified: cfe/trunk/lib/AST/Decl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=262493&r1=262492&r2=262493&view=diff ============================================================================== --- cfe/trunk/lib/AST/Decl.cpp (original) +++ cfe/trunk/lib/AST/Decl.cpp Wed Mar 2 11:28:48 2016 @@ -3905,6 +3905,29 @@ TranslationUnitDecl *TranslationUnitDecl return new (C, (DeclContext *)nullptr) TranslationUnitDecl(C); } +void PragmaCommentDecl::anchor() { } + +PragmaCommentDecl *PragmaCommentDecl::Create(const ASTContext &C, + TranslationUnitDecl *DC, + SourceLocation CommentLoc, + PragmaMSCommentKind CommentKind, + StringRef Arg) { + PragmaCommentDecl *PCD = + new (C, DC, additionalSizeToAlloc<char>(Arg.size() + 1)) + PragmaCommentDecl(DC, CommentLoc, CommentKind); + memcpy(PCD->getTrailingObjects<char>(), Arg.data(), Arg.size()); + PCD->getTrailingObjects<char>()[Arg.size()] = '\0'; + return PCD; +} + +PragmaCommentDecl *PragmaCommentDecl::CreateDeserialized(ASTContext &C, + unsigned ID, + unsigned ArgSize) { + return new (C, ID, additionalSizeToAlloc<char>(ArgSize + 1)) + PragmaCommentDecl(nullptr, SourceLocation(), PCK_Unknown); +} + + void ExternCContextDecl::anchor() { } ExternCContextDecl *ExternCContextDecl::Create(const ASTContext &C, Modified: cfe/trunk/lib/AST/DeclBase.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=262493&r1=262492&r2=262493&view=diff ============================================================================== --- cfe/trunk/lib/AST/DeclBase.cpp (original) +++ cfe/trunk/lib/AST/DeclBase.cpp Wed Mar 2 11:28:48 2016 @@ -641,6 +641,7 @@ unsigned Decl::getIdentifierNamespaceFor case FileScopeAsm: case StaticAssert: case ObjCPropertyImpl: + case PragmaComment: case Block: case Captured: case TranslationUnit: Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=262493&r1=262492&r2=262493&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGDecl.cpp (original) +++ cfe/trunk/lib/CodeGen/CGDecl.cpp Wed Mar 2 11:28:48 2016 @@ -71,6 +71,7 @@ void CodeGenFunction::EmitDecl(const Dec case Decl::ObjCImplementation: case Decl::ObjCProperty: case Decl::ObjCCompatibleAlias: + case Decl::PragmaComment: case Decl::AccessSpec: case Decl::LinkageSpec: case Decl::ObjCPropertyImpl: Modified: cfe/trunk/lib/CodeGen/CodeGenAction.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenAction.cpp?rev=262493&r1=262492&r2=262493&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CodeGenAction.cpp (original) +++ cfe/trunk/lib/CodeGen/CodeGenAction.cpp Wed Mar 2 11:28:48 2016 @@ -205,19 +205,11 @@ namespace clang { Gen->HandleVTable(RD); } - void HandleLinkerOption(llvm::StringRef Opts) override { - Gen->HandleLinkerOption(Opts); - } - void HandleDetectMismatch(llvm::StringRef Name, llvm::StringRef Value) override { Gen->HandleDetectMismatch(Name, Value); } - void HandleDependentLibrary(llvm::StringRef Opts) override { - Gen->HandleDependentLibrary(Opts); - } - static void InlineAsmDiagHandler(const llvm::SMDiagnostic &SM,void *Context, unsigned LocCookie) { SourceLocation Loc = SourceLocation::getFromRawEncoding(LocCookie); Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=262493&r1=262492&r2=262493&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original) +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Wed Mar 2 11:28:48 2016 @@ -3689,6 +3689,25 @@ void CodeGenModule::EmitTopLevelDecl(Dec ObjCRuntime->RegisterAlias(cast<ObjCCompatibleAliasDecl>(D)); break; + case Decl::PragmaComment: { + const auto *PCD = cast<PragmaCommentDecl>(D); + switch (PCD->getCommentKind()) { + case PCK_Unknown: + llvm_unreachable("unexpected pragma comment kind"); + case PCK_Linker: + AppendLinkerOptions(PCD->getArg()); + break; + case PCK_Lib: + AddDependentLib(PCD->getArg()); + break; + case PCK_Compiler: + case PCK_ExeStr: + case PCK_User: + break; // We ignore all of these. + } + break; + } + case Decl::LinkageSpec: EmitLinkageSpec(cast<LinkageSpecDecl>(D)); break; Modified: cfe/trunk/lib/CodeGen/ModuleBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ModuleBuilder.cpp?rev=262493&r1=262492&r2=262493&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/ModuleBuilder.cpp (original) +++ cfe/trunk/lib/CodeGen/ModuleBuilder.cpp Wed Mar 2 11:28:48 2016 @@ -104,9 +104,9 @@ namespace { *M, Diags, CoverageInfo)); for (auto &&Lib : CodeGenOpts.DependentLibraries) - HandleDependentLibrary(Lib); + Builder->AddDependentLib(Lib); for (auto &&Opt : CodeGenOpts.LinkerOptions) - HandleLinkerOption(Opt); + Builder->AppendLinkerOptions(Opt); } void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override { @@ -234,18 +234,10 @@ namespace { Builder->EmitVTable(RD); } - void HandleLinkerOption(llvm::StringRef Opts) override { - Builder->AppendLinkerOptions(Opts); - } - void HandleDetectMismatch(llvm::StringRef Name, llvm::StringRef Value) override { Builder->AddDetectMismatch(Name, Value); } - - void HandleDependentLibrary(llvm::StringRef Lib) override { - Builder->AddDependentLib(Lib); - } }; } Modified: cfe/trunk/lib/Frontend/MultiplexConsumer.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/MultiplexConsumer.cpp?rev=262493&r1=262492&r2=262493&view=diff ============================================================================== --- cfe/trunk/lib/Frontend/MultiplexConsumer.cpp (original) +++ cfe/trunk/lib/Frontend/MultiplexConsumer.cpp Wed Mar 2 11:28:48 2016 @@ -317,21 +317,11 @@ void MultiplexConsumer::HandleImplicitIm Consumer->HandleImplicitImportDecl(D); } -void MultiplexConsumer::HandleLinkerOption(llvm::StringRef Opts) { - for (auto &Consumer : Consumers) - Consumer->HandleLinkerOption(Opts); -} - void MultiplexConsumer::HandleDetectMismatch(llvm::StringRef Name, llvm::StringRef Value) { for (auto &Consumer : Consumers) Consumer->HandleDetectMismatch(Name, Value); } -void MultiplexConsumer::HandleDependentLibrary(llvm::StringRef Lib) { - for (auto &Consumer : Consumers) - Consumer->HandleDependentLibrary(Lib); -} - void MultiplexConsumer::CompleteTentativeDefinition(VarDecl *D) { for (auto &Consumer : Consumers) Consumer->CompleteTentativeDefinition(D); Modified: cfe/trunk/lib/Parse/ParsePragma.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParsePragma.cpp?rev=262493&r1=262492&r2=262493&view=diff ============================================================================== --- cfe/trunk/lib/Parse/ParsePragma.cpp (original) +++ cfe/trunk/lib/Parse/ParsePragma.cpp Wed Mar 2 11:28:48 2016 @@ -13,6 +13,7 @@ #include "RAIIObjectsForParser.h" #include "clang/AST/ASTContext.h" +#include "clang/Basic/PragmaKinds.h" #include "clang/Basic/TargetInfo.h" #include "clang/Lex/Preprocessor.h" #include "clang/Parse/ParseDiagnostic.h" @@ -1793,22 +1794,22 @@ void PragmaCommentHandler::HandlePragma( // Verify that this is one of the 5 whitelisted options. IdentifierInfo *II = Tok.getIdentifierInfo(); - Sema::PragmaMSCommentKind Kind = - llvm::StringSwitch<Sema::PragmaMSCommentKind>(II->getName()) - .Case("linker", Sema::PCK_Linker) - .Case("lib", Sema::PCK_Lib) - .Case("compiler", Sema::PCK_Compiler) - .Case("exestr", Sema::PCK_ExeStr) - .Case("user", Sema::PCK_User) - .Default(Sema::PCK_Unknown); - if (Kind == Sema::PCK_Unknown) { + PragmaMSCommentKind Kind = + llvm::StringSwitch<PragmaMSCommentKind>(II->getName()) + .Case("linker", PCK_Linker) + .Case("lib", PCK_Lib) + .Case("compiler", PCK_Compiler) + .Case("exestr", PCK_ExeStr) + .Case("user", PCK_User) + .Default(PCK_Unknown); + if (Kind == PCK_Unknown) { PP.Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind); return; } // On PS4, issue a warning about any pragma comments other than // #pragma comment lib. - if (PP.getTargetInfo().getTriple().isPS4() && Kind != Sema::PCK_Lib) { + if (PP.getTargetInfo().getTriple().isPS4() && Kind != PCK_Lib) { PP.Diag(Tok.getLocation(), diag::warn_pragma_comment_ignored) << II->getName(); return; @@ -1844,7 +1845,7 @@ void PragmaCommentHandler::HandlePragma( if (PP.getPPCallbacks()) PP.getPPCallbacks()->PragmaComment(CommentLoc, II, ArgumentString); - Actions.ActOnPragmaMSComment(Kind, ArgumentString); + Actions.ActOnPragmaMSComment(CommentLoc, Kind, ArgumentString); } // #pragma clang optimize off Modified: cfe/trunk/lib/Sema/SemaAttr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAttr.cpp?rev=262493&r1=262492&r2=262493&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaAttr.cpp (original) +++ cfe/trunk/lib/Sema/SemaAttr.cpp Wed Mar 2 11:28:48 2016 @@ -269,23 +269,12 @@ void Sema::ActOnPragmaMSStruct(PragmaMSS MSStructPragmaOn = (Kind == PMSST_ON); } -void Sema::ActOnPragmaMSComment(PragmaMSCommentKind Kind, StringRef Arg) { - // FIXME: Serialize this. - switch (Kind) { - case PCK_Unknown: - llvm_unreachable("unexpected pragma comment kind"); - case PCK_Linker: - Consumer.HandleLinkerOption(Arg); - return; - case PCK_Lib: - Consumer.HandleDependentLibrary(Arg); - return; - case PCK_Compiler: - case PCK_ExeStr: - case PCK_User: - return; // We ignore all of these. - } - llvm_unreachable("invalid pragma comment kind"); +void Sema::ActOnPragmaMSComment(SourceLocation CommentLoc, + PragmaMSCommentKind Kind, StringRef Arg) { + auto *PCD = PragmaCommentDecl::Create( + Context, Context.getTranslationUnitDecl(), CommentLoc, Kind, Arg); + Context.getTranslationUnitDecl()->addDecl(PCD); + Consumer.HandleTopLevelDecl(DeclGroupRef(PCD)); } void Sema::ActOnPragmaDetectMismatch(StringRef Name, StringRef Value) { Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=262493&r1=262492&r2=262493&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Mar 2 11:28:48 2016 @@ -334,6 +334,11 @@ TemplateDeclInstantiator::VisitTranslati } Decl * +TemplateDeclInstantiator::VisitPragmaCommentDecl(PragmaCommentDecl *D) { + llvm_unreachable("pragma comment cannot be instantiated"); +} + +Decl * TemplateDeclInstantiator::VisitExternCContextDecl(ExternCContextDecl *D) { llvm_unreachable("extern \"C\" context cannot be instantiated"); } Modified: cfe/trunk/lib/Serialization/ASTCommon.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTCommon.cpp?rev=262493&r1=262492&r2=262493&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTCommon.cpp (original) +++ cfe/trunk/lib/Serialization/ASTCommon.cpp Wed Mar 2 11:28:48 2016 @@ -319,6 +319,7 @@ bool serialization::isRedeclarableDeclKi case Decl::ObjCCompatibleAlias: case Decl::LinkageSpec: case Decl::ObjCPropertyImpl: + case Decl::PragmaComment: case Decl::FileScopeAsm: case Decl::AccessSpec: case Decl::Friend: Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=262493&r1=262492&r2=262493&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Wed Mar 2 11:28:48 2016 @@ -68,6 +68,10 @@ namespace clang { return Reader.ReadDeclID(F, R, I); } + std::string ReadString(const RecordData &R, unsigned &I) { + return Reader.ReadString(R, I); + } + void ReadDeclIDList(SmallVectorImpl<DeclID> &IDs) { for (unsigned I = 0, Size = Record[Idx++]; I != Size; ++I) IDs.push_back(ReadDeclID(Record, Idx)); @@ -238,6 +242,7 @@ namespace clang { } void VisitDecl(Decl *D); + void VisitPragmaCommentDecl(PragmaCommentDecl *D); void VisitTranslationUnitDecl(TranslationUnitDecl *TU); void VisitNamedDecl(NamedDecl *ND); void VisitLabelDecl(LabelDecl *LD); @@ -538,6 +543,15 @@ void ASTDeclReader::VisitDecl(Decl *D) { } } +void ASTDeclReader::VisitPragmaCommentDecl(PragmaCommentDecl *D) { + VisitDecl(D); + D->setLocation(ReadSourceLocation(Record, Idx)); + D->CommentKind = (PragmaMSCommentKind)Record[Idx++]; + std::string Arg = ReadString(Record, Idx); + memcpy(D->getTrailingObjects<char>(), Arg.data(), Arg.size()); + D->getTrailingObjects<char>()[Arg.size()] = '\0'; +} + void ASTDeclReader::VisitTranslationUnitDecl(TranslationUnitDecl *TU) { llvm_unreachable("Translation units are not serialized"); } @@ -2418,6 +2432,7 @@ static bool isConsumerInterestedIn(Decl isa<ObjCProtocolDecl>(D) || isa<ObjCImplDecl>(D) || isa<ImportDecl>(D) || + isa<PragmaCommentDecl>(D) || isa<OMPThreadPrivateDecl>(D)) return true; if (VarDecl *Var = dyn_cast<VarDecl>(D)) @@ -3335,6 +3350,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID I case DECL_OMP_CAPTUREDEXPR: D = OMPCapturedExprDecl::CreateDeserialized(Context, ID); break; + case DECL_PRAGMA_COMMENT: + D = PragmaCommentDecl::CreateDeserialized(Context, ID, Record[Idx++]); + break; case DECL_EMPTY: D = EmptyDecl::CreateDeserialized(Context, ID); break; Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=262493&r1=262492&r2=262493&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original) +++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Wed Mar 2 11:28:48 2016 @@ -49,6 +49,7 @@ namespace clang { void Visit(Decl *D); void VisitDecl(Decl *D); + void VisitPragmaCommentDecl(PragmaCommentDecl *D); void VisitTranslationUnitDecl(TranslationUnitDecl *D); void VisitNamedDecl(NamedDecl *D); void VisitLabelDecl(LabelDecl *LD); @@ -315,6 +316,16 @@ void ASTDeclWriter::VisitDecl(Decl *D) { } } +void ASTDeclWriter::VisitPragmaCommentDecl(PragmaCommentDecl *D) { + StringRef Arg = D->getArg(); + Record.push_back(Arg.size()); + VisitDecl(D); + Writer.AddSourceLocation(D->getLocStart(), Record); + Record.push_back(D->getCommentKind()); + Writer.AddString(Arg, Record); + Code = serialization::DECL_PRAGMA_COMMENT; +} + void ASTDeclWriter::VisitTranslationUnitDecl(TranslationUnitDecl *D) { llvm_unreachable("Translation units aren't directly serialized"); } Added: cfe/trunk/test/PCH/pragma-comment.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/pragma-comment.c?rev=262493&view=auto ============================================================================== --- cfe/trunk/test/PCH/pragma-comment.c (added) +++ cfe/trunk/test/PCH/pragma-comment.c Wed Mar 2 11:28:48 2016 @@ -0,0 +1,22 @@ +// Test this without pch. +// RUN: %clang_cc1 %s -Wunknown-pragmas -Werror -triple x86_64-pc-win32 -fms-extensions -emit-llvm -include %s -o - | FileCheck %s + +// Test with pch. +// RUN: %clang_cc1 %s -Wunknown-pragmas -Werror -triple x86_64-pc-win32 -fms-extensions -emit-pch -o %t +// RUN: %clang_cc1 %s -Wunknown-pragmas -Werror -triple x86_64-pc-win32 -fms-extensions -emit-llvm -include-pch %t -o - | FileCheck %s + +// The first run line creates a pch, and since at that point HEADER is not +// defined, the only thing contained in the pch is the pragma. The second line +// then includes that pch, so HEADER is defined and the actual code is compiled. +// The check then makes sure that the pragma is in effect in the file that +// includes the pch. + +#ifndef HEADER +#define HEADER +#pragma comment(lib, "foo.lib") + +#else + +// CHECK: "/DEFAULTLIB:foo.lib" + +#endif Modified: cfe/trunk/tools/libclang/CIndex.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=262493&r1=262492&r2=262493&view=diff ============================================================================== --- cfe/trunk/tools/libclang/CIndex.cpp (original) +++ cfe/trunk/tools/libclang/CIndex.cpp Wed Mar 2 11:28:48 2016 @@ -5586,6 +5586,7 @@ CXCursor clang_getCursorDefinition(CXCur case Decl::OMPThreadPrivate: case Decl::ObjCTypeParam: case Decl::BuiltinTemplate: + case Decl::PragmaComment: return C; // Declaration kinds that don't make any sense here, but are _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits