summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2016-03-02 17:28:48 +0000
committerNico Weber <nicolasweber@gmx.de>2016-03-02 17:28:48 +0000
commit6622029d5ee15bfddacbda4825804ee89f8c30e6 (patch)
treebb7f94cffd80e3d0572c3f372ef4e68f57ee2ce9 /clang/lib
parent3ca9ee0c537768b92087f24d2609756ba72cda4f (diff)
downloadbcm5719-llvm-6622029d5ee15bfddacbda4825804ee89f8c30e6.tar.gz
bcm5719-llvm-6622029d5ee15bfddacbda4825804ee89f8c30e6.zip
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 llvm-svn: 262493
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTContext.cpp4
-rw-r--r--clang/lib/AST/ASTDumper.cpp16
-rw-r--r--clang/lib/AST/Decl.cpp23
-rw-r--r--clang/lib/AST/DeclBase.cpp1
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp1
-rw-r--r--clang/lib/CodeGen/CodeGenAction.cpp8
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp19
-rw-r--r--clang/lib/CodeGen/ModuleBuilder.cpp12
-rw-r--r--clang/lib/Frontend/MultiplexConsumer.cpp10
-rw-r--r--clang/lib/Parse/ParsePragma.cpp23
-rw-r--r--clang/lib/Sema/SemaAttr.cpp23
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp5
-rw-r--r--clang/lib/Serialization/ASTCommon.cpp1
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp18
-rw-r--r--clang/lib/Serialization/ASTWriterDecl.cpp11
15 files changed, 118 insertions, 57 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index dad6d1a9d4f..0579bca3fe7 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -8503,7 +8503,9 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
// 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;
diff --git a/clang/lib/AST/ASTDumper.cpp b/clang/lib/AST/ASTDumper.cpp
index 809b1dd6bd4..e0ef80d475f 100644
--- a/clang/lib/AST/ASTDumper.cpp
+++ b/clang/lib/AST/ASTDumper.cpp
@@ -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 ImportDecl *D) {
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
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 7378c44178b..e22f1bcf0f2 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -3905,6 +3905,29 @@ TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) {
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,
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index d41d25f7a44..91bc809cf48 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -641,6 +641,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case FileScopeAsm:
case StaticAssert:
case ObjCPropertyImpl:
+ case PragmaComment:
case Block:
case Captured:
case TranslationUnit:
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 5b88ef1830f..f9a6b06a4a9 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -71,6 +71,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) {
case Decl::ObjCImplementation:
case Decl::ObjCProperty:
case Decl::ObjCCompatibleAlias:
+ case Decl::PragmaComment:
case Decl::AccessSpec:
case Decl::LinkageSpec:
case Decl::ObjCPropertyImpl:
diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp
index 3d333c88f99..8d081144902 100644
--- a/clang/lib/CodeGen/CodeGenAction.cpp
+++ b/clang/lib/CodeGen/CodeGenAction.cpp
@@ -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);
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index b98094f6656..887c53331f6 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -3689,6 +3689,25 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
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;
diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp
index 234a7736065..968cc46f7e7 100644
--- a/clang/lib/CodeGen/ModuleBuilder.cpp
+++ b/clang/lib/CodeGen/ModuleBuilder.cpp
@@ -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);
- }
};
}
diff --git a/clang/lib/Frontend/MultiplexConsumer.cpp b/clang/lib/Frontend/MultiplexConsumer.cpp
index 12cd86af83c..95e9bec6a4e 100644
--- a/clang/lib/Frontend/MultiplexConsumer.cpp
+++ b/clang/lib/Frontend/MultiplexConsumer.cpp
@@ -317,21 +317,11 @@ void MultiplexConsumer::HandleImplicitImportDecl(ImportDecl *D) {
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);
diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp
index 42f8b518b17..06c1a17bdd4 100644
--- a/clang/lib/Parse/ParsePragma.cpp
+++ b/clang/lib/Parse/ParsePragma.cpp
@@ -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(Preprocessor &PP,
// 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(Preprocessor &PP,
if (PP.getPPCallbacks())
PP.getPPCallbacks()->PragmaComment(CommentLoc, II, ArgumentString);
- Actions.ActOnPragmaMSComment(Kind, ArgumentString);
+ Actions.ActOnPragmaMSComment(CommentLoc, Kind, ArgumentString);
}
// #pragma clang optimize off
diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
index f3145713d58..1900d80b217 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -269,23 +269,12 @@ void Sema::ActOnPragmaMSStruct(PragmaMSStructKind Kind) {
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) {
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index fdf1c73bfc6..844bdd1fa07 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -334,6 +334,11 @@ TemplateDeclInstantiator::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
}
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");
}
diff --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp
index 0b4772a5353..067653dfbf2 100644
--- a/clang/lib/Serialization/ASTCommon.cpp
+++ b/clang/lib/Serialization/ASTCommon.cpp
@@ -319,6 +319,7 @@ bool serialization::isRedeclarableDeclKind(unsigned Kind) {
case Decl::ObjCCompatibleAlias:
case Decl::LinkageSpec:
case Decl::ObjCPropertyImpl:
+ case Decl::PragmaComment:
case Decl::FileScopeAsm:
case Decl::AccessSpec:
case Decl::Friend:
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index f484345dfc5..a7eded1a2fd 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -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 *D, bool HasBody) {
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 ID) {
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;
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index 6ff3f954168..bf36af6bd5a 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -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");
}
OpenPOWER on IntegriCloud