summaryrefslogtreecommitdiffstats
path: root/lib/Frontend
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2010-03-03 17:28:16 +0000
committerrdivacky <rdivacky@FreeBSD.org>2010-03-03 17:28:16 +0000
commitdf90325d4c0a65ee64d2dae3ed9b5b34f7418533 (patch)
treee1a885aadfd80632f5bd70d4bd2d37e715e35a79 /lib/Frontend
parentfd035e6496665b1f1197868e21cb0a4594e8db6e (diff)
downloadFreeBSD-src-df90325d4c0a65ee64d2dae3ed9b5b34f7418533.zip
FreeBSD-src-df90325d4c0a65ee64d2dae3ed9b5b34f7418533.tar.gz
Update clang to 97654.
Diffstat (limited to 'lib/Frontend')
-rw-r--r--lib/Frontend/ASTUnit.cpp76
-rw-r--r--lib/Frontend/CMakeLists.txt2
-rw-r--r--lib/Frontend/CacheTokens.cpp7
-rw-r--r--lib/Frontend/CodeGenAction.cpp (renamed from lib/Frontend/Backend.cpp)114
-rw-r--r--lib/Frontend/CompilerInstance.cpp2
-rw-r--r--lib/Frontend/CompilerInvocation.cpp3
-rw-r--r--lib/Frontend/FrontendActions.cpp42
-rw-r--r--lib/Frontend/InitHeaderSearch.cpp4
-rw-r--r--lib/Frontend/InitPreprocessor.cpp3
-rw-r--r--lib/Frontend/PCHReaderDecl.cpp25
-rw-r--r--lib/Frontend/PCHWriter.cpp11
-rw-r--r--lib/Frontend/PCHWriterDecl.cpp11
-rw-r--r--lib/Frontend/PrintPreprocessedOutput.cpp7
-rw-r--r--lib/Frontend/RewriteObjC.cpp392
-rw-r--r--lib/Frontend/TextDiagnosticPrinter.cpp10
15 files changed, 527 insertions, 182 deletions
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index a0c4889..ef14df1 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -36,11 +36,11 @@
using namespace clang;
ASTUnit::ASTUnit(bool _MainFileIsAST)
- : tempFile(false), MainFileIsAST(_MainFileIsAST) {
+ : MainFileIsAST(_MainFileIsAST) {
}
ASTUnit::~ASTUnit() {
- if (tempFile)
- llvm::sys::Path(getPCHFileName()).eraseFromDisk();
+ for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I)
+ TemporaryFiles[I].eraseFromDisk();
}
namespace {
@@ -90,8 +90,46 @@ public:
}
};
+class StoredDiagnosticClient : public DiagnosticClient {
+ llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags;
+
+public:
+ explicit StoredDiagnosticClient(
+ llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags)
+ : StoredDiags(StoredDiags) { }
+
+ virtual void HandleDiagnostic(Diagnostic::Level Level,
+ const DiagnosticInfo &Info);
+};
+
+/// \brief RAII object that optionally captures diagnostics, if
+/// there is no diagnostic client to capture them already.
+class CaptureDroppedDiagnostics {
+ Diagnostic &Diags;
+ StoredDiagnosticClient Client;
+ DiagnosticClient *PreviousClient;
+
+public:
+ CaptureDroppedDiagnostics(bool RequestCapture, Diagnostic &Diags,
+ llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiags)
+ : Diags(Diags), Client(StoredDiags), PreviousClient(Diags.getClient())
+ {
+ if (RequestCapture || Diags.getClient() == 0)
+ Diags.setClient(&Client);
+ }
+
+ ~CaptureDroppedDiagnostics() {
+ Diags.setClient(PreviousClient);
+ }
+};
+
} // anonymous namespace
+void StoredDiagnosticClient::HandleDiagnostic(Diagnostic::Level Level,
+ const DiagnosticInfo &Info) {
+ StoredDiags.push_back(StoredDiagnostic(Level, Info));
+}
+
const std::string &ASTUnit::getOriginalSourceFileName() {
return OriginalSourceFile;
}
@@ -105,11 +143,16 @@ ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename,
Diagnostic &Diags,
bool OnlyLocalDecls,
RemappedFile *RemappedFiles,
- unsigned NumRemappedFiles) {
+ unsigned NumRemappedFiles,
+ bool CaptureDiagnostics) {
llvm::OwningPtr<ASTUnit> AST(new ASTUnit(true));
AST->OnlyLocalDecls = OnlyLocalDecls;
AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager()));
+ // If requested, capture diagnostics in the ASTUnit.
+ CaptureDroppedDiagnostics Capture(CaptureDiagnostics, Diags,
+ AST->Diagnostics);
+
for (unsigned I = 0; I != NumRemappedFiles; ++I) {
// Create the file entry for the file that we're mapping from.
const FileEntry *FromFile
@@ -119,6 +162,7 @@ ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename,
if (!FromFile) {
Diags.Report(diag::err_fe_remap_missing_from_file)
<< RemappedFiles[I].first;
+ delete RemappedFiles[I].second;
continue;
}
@@ -231,7 +275,8 @@ public:
ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI,
Diagnostic &Diags,
- bool OnlyLocalDecls) {
+ bool OnlyLocalDecls,
+ bool CaptureDiagnostics) {
// Create the compiler instance to use for building the AST.
CompilerInstance Clang;
llvm::OwningPtr<ASTUnit> AST;
@@ -245,8 +290,13 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI,
// Create the target instance.
Clang.setTarget(TargetInfo::CreateTargetInfo(Clang.getDiagnostics(),
Clang.getTargetOpts()));
- if (!Clang.hasTarget())
- goto error;
+ if (!Clang.hasTarget()) {
+ Clang.takeSourceManager();
+ Clang.takeFileManager();
+ Clang.takeDiagnosticClient();
+ Clang.takeDiagnostics();
+ return 0;
+ }
// Inform the target of the language options.
//
@@ -261,10 +311,14 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI,
// Create the AST unit.
AST.reset(new ASTUnit(false));
-
AST->OnlyLocalDecls = OnlyLocalDecls;
AST->OriginalSourceFile = Clang.getFrontendOpts().Inputs[0].second;
+ // Capture any diagnostics that would otherwise be dropped.
+ CaptureDroppedDiagnostics Capture(CaptureDiagnostics,
+ Clang.getDiagnostics(),
+ AST->Diagnostics);
+
// Create a file manager object to provide access to and cache the filesystem.
Clang.setFileManager(&AST->getFileManager());
@@ -312,7 +366,8 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
llvm::StringRef ResourceFilesPath,
bool OnlyLocalDecls,
RemappedFile *RemappedFiles,
- unsigned NumRemappedFiles) {
+ unsigned NumRemappedFiles,
+ bool CaptureDiagnostics) {
llvm::SmallVector<const char *, 16> Args;
Args.push_back("<clang>"); // FIXME: Remove dummy argument.
Args.insert(Args.end(), ArgBegin, ArgEnd);
@@ -363,5 +418,6 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath;
CI->getFrontendOpts().DisableFree = true;
- return LoadFromCompilerInvocation(CI.take(), Diags, OnlyLocalDecls);
+ return LoadFromCompilerInvocation(CI.take(), Diags, OnlyLocalDecls,
+ CaptureDiagnostics);
}
diff --git a/lib/Frontend/CMakeLists.txt b/lib/Frontend/CMakeLists.txt
index 1d0b5c1..b69ad97 100644
--- a/lib/Frontend/CMakeLists.txt
+++ b/lib/Frontend/CMakeLists.txt
@@ -5,8 +5,8 @@ add_clang_library(clangFrontend
ASTMerge.cpp
ASTUnit.cpp
AnalysisConsumer.cpp
- Backend.cpp
CacheTokens.cpp
+ CodeGenAction.cpp
CompilerInstance.cpp
CompilerInvocation.cpp
DeclXML.cpp
diff --git a/lib/Frontend/CacheTokens.cpp b/lib/Frontend/CacheTokens.cpp
index 7326937..09b5b45 100644
--- a/lib/Frontend/CacheTokens.cpp
+++ b/lib/Frontend/CacheTokens.cpp
@@ -190,12 +190,7 @@ class PTHWriter {
void Emit16(uint32_t V) { ::Emit16(Out, V); }
- void Emit24(uint32_t V) {
- Out << (unsigned char)(V);
- Out << (unsigned char)(V >> 8);
- Out << (unsigned char)(V >> 16);
- assert((V >> 24) == 0);
- }
+ void Emit24(uint32_t V) { ::Emit24(Out, V); }
void Emit32(uint32_t V) { ::Emit32(Out, V); }
diff --git a/lib/Frontend/Backend.cpp b/lib/Frontend/CodeGenAction.cpp
index f5291a9..b1795a3 100644
--- a/lib/Frontend/Backend.cpp
+++ b/lib/Frontend/CodeGenAction.cpp
@@ -1,4 +1,4 @@
-//===--- Backend.cpp - Interface to LLVM backend technologies -------------===//
+//===--- CodeGenAction.cpp - LLVM Code Generation Frontend Action ---------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/Frontend/ASTConsumers.h"
+#include "clang/Frontend/CodeGenAction.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclGroup.h"
@@ -15,6 +15,8 @@
#include "clang/Basic/TargetOptions.h"
#include "clang/CodeGen/CodeGenOptions.h"
#include "clang/CodeGen/ModuleBuilder.h"
+#include "clang/Frontend/ASTConsumers.h"
+#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
@@ -37,6 +39,14 @@ using namespace clang;
using namespace llvm;
namespace {
+ enum BackendAction {
+ Backend_EmitAssembly, ///< Emit native assembly files
+ Backend_EmitBC, ///< Emit LLVM bitcode files
+ Backend_EmitLL, ///< Emit human-readable LLVM assembly
+ Backend_EmitNothing, ///< Don't emit anything (benchmarking mode)
+ Backend_EmitObj ///< Emit native object files
+ };
+
class BackendConsumer : public ASTConsumer {
Diagnostic &Diags;
BackendAction Action;
@@ -52,7 +62,7 @@ namespace {
llvm::OwningPtr<CodeGenerator> Gen;
- llvm::Module *TheModule;
+ llvm::OwningPtr<llvm::Module> TheModule;
llvm::TargetData *TheTargetData;
mutable FunctionPassManager *CodeGenPasses;
@@ -87,7 +97,7 @@ namespace {
LLVMIRGeneration("LLVM IR Generation Time"),
CodeGenerationTime("Code Generation Time"),
Gen(CreateLLVMCodeGen(Diags, infile, compopts, C)),
- TheModule(0), TheTargetData(0),
+ TheTargetData(0),
CodeGenPasses(0), PerModulePasses(0), PerFunctionPasses(0) {
if (AsmOutStream)
@@ -99,12 +109,13 @@ namespace {
~BackendConsumer() {
delete TheTargetData;
- delete TheModule;
delete CodeGenPasses;
delete PerModulePasses;
delete PerFunctionPasses;
}
+ llvm::Module *takeModule() { return TheModule.take(); }
+
virtual void Initialize(ASTContext &Ctx) {
Context = &Ctx;
@@ -113,7 +124,7 @@ namespace {
Gen->Initialize(Ctx);
- TheModule = Gen->GetModule();
+ TheModule.reset(Gen->GetModule());
TheTargetData = new llvm::TargetData(Ctx.Target.getTargetDescription());
if (llvm::TimePassesIsEnabled)
@@ -169,7 +180,7 @@ namespace {
FunctionPassManager *BackendConsumer::getCodeGenPasses() const {
if (!CodeGenPasses) {
- CodeGenPasses = new FunctionPassManager(TheModule);
+ CodeGenPasses = new FunctionPassManager(&*TheModule);
CodeGenPasses->add(new TargetData(*TheTargetData));
}
@@ -187,7 +198,7 @@ PassManager *BackendConsumer::getPerModulePasses() const {
FunctionPassManager *BackendConsumer::getPerFunctionPasses() const {
if (!PerFunctionPasses) {
- PerFunctionPasses = new FunctionPassManager(TheModule);
+ PerFunctionPasses = new FunctionPassManager(&*TheModule);
PerFunctionPasses->add(new TargetData(*TheTargetData));
}
@@ -303,12 +314,21 @@ bool BackendConsumer::AddEmitPasses() {
case 3: OptLevel = CodeGenOpt::Aggressive; break;
}
+ // Request that addPassesToEmitFile run the Verifier after running
+ // passes which modify the IR.
+#ifndef NDEBUG
+ bool DisableVerify = false;
+#else
+ bool DisableVerify = true;
+#endif
+
// Normal mode, emit a .s or .o file by running the code generator. Note,
// this also adds codegenerator level optimization passes.
TargetMachine::CodeGenFileType CGFT = TargetMachine::CGFT_AssemblyFile;
if (Action == Backend_EmitObj)
CGFT = TargetMachine::CGFT_ObjectFile;
- if (TM->addPassesToEmitFile(*PM, FormattedOutStream, CGFT, OptLevel)) {
+ if (TM->addPassesToEmitFile(*PM, FormattedOutStream, CGFT, OptLevel,
+ DisableVerify)) {
Diags.Report(diag::err_fe_unable_to_interface_with_target);
return false;
}
@@ -381,11 +401,12 @@ void BackendConsumer::EmitAssembly() {
if (!M) {
// The module has been released by IR gen on failures, do not
// double free.
- TheModule = 0;
+ TheModule.take();
return;
}
- assert(TheModule == M && "Unexpected module change during IR generation");
+ assert(TheModule.get() == M &&
+ "Unexpected module change during IR generation");
CreatePasses();
if (!AddEmitPasses())
@@ -419,15 +440,64 @@ void BackendConsumer::EmitAssembly() {
}
}
-ASTConsumer *clang::CreateBackendConsumer(BackendAction Action,
- Diagnostic &Diags,
- const LangOptions &LangOpts,
- const CodeGenOptions &CodeGenOpts,
- const TargetOptions &TargetOpts,
- bool TimePasses,
- const std::string& InFile,
- llvm::raw_ostream* OS,
- LLVMContext& C) {
- return new BackendConsumer(Action, Diags, LangOpts, CodeGenOpts,
- TargetOpts, TimePasses, InFile, OS, C);
+//
+
+CodeGenAction::CodeGenAction(unsigned _Act) : Act(_Act) {}
+
+CodeGenAction::~CodeGenAction() {}
+
+void CodeGenAction::EndSourceFileAction() {
+ // If the consumer creation failed, do nothing.
+ if (!getCompilerInstance().hasASTConsumer())
+ return;
+
+ // Steal the module from the consumer.
+ BackendConsumer *Consumer = static_cast<BackendConsumer*>(
+ &getCompilerInstance().getASTConsumer());
+
+ TheModule.reset(Consumer->takeModule());
+}
+
+llvm::Module *CodeGenAction::takeModule() {
+ return TheModule.take();
}
+
+ASTConsumer *CodeGenAction::CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile) {
+ BackendAction BA = static_cast<BackendAction>(Act);
+ llvm::OwningPtr<llvm::raw_ostream> OS;
+ switch (BA) {
+ case Backend_EmitAssembly:
+ OS.reset(CI.createDefaultOutputFile(false, InFile, "s"));
+ break;
+ case Backend_EmitLL:
+ OS.reset(CI.createDefaultOutputFile(false, InFile, "ll"));
+ break;
+ case Backend_EmitBC:
+ OS.reset(CI.createDefaultOutputFile(true, InFile, "bc"));
+ break;
+ case Backend_EmitNothing:
+ break;
+ case Backend_EmitObj:
+ OS.reset(CI.createDefaultOutputFile(true, InFile, "o"));
+ break;
+ }
+ if (BA != Backend_EmitNothing && !OS)
+ return 0;
+
+ return new BackendConsumer(BA, CI.getDiagnostics(), CI.getLangOpts(),
+ CI.getCodeGenOpts(), CI.getTargetOpts(),
+ CI.getFrontendOpts().ShowTimers, InFile, OS.take(),
+ CI.getLLVMContext());
+}
+
+EmitAssemblyAction::EmitAssemblyAction()
+ : CodeGenAction(Backend_EmitAssembly) {}
+
+EmitBCAction::EmitBCAction() : CodeGenAction(Backend_EmitBC) {}
+
+EmitLLVMAction::EmitLLVMAction() : CodeGenAction(Backend_EmitLL) {}
+
+EmitLLVMOnlyAction::EmitLLVMOnlyAction() : CodeGenAction(Backend_EmitNothing) {}
+
+EmitObjAction::EmitObjAction() : CodeGenAction(Backend_EmitObj) {}
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index 917cbd7..1831ca5 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -102,7 +102,7 @@ namespace {
void BinaryDiagnosticSerializer::HandleDiagnostic(Diagnostic::Level DiagLevel,
const DiagnosticInfo &Info) {
- Info.Serialize(DiagLevel, OS);
+ StoredDiagnostic(DiagLevel, Info).Serialize(OS);
}
static void SetUpBuildDumpLog(const DiagnosticOptions &DiagOpts,
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index a193ac8..64a42bc 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -180,6 +180,8 @@ static void CodeGenOptsToArgs(const CodeGenOptions &Opts,
Res.push_back("-mrelocation-model");
Res.push_back(Opts.RelocationModel);
}
+ if (Opts.CXXCtorDtorAliases)
+ Res.push_back("-mconstructor-aliases");
if (!Opts.VerifyModule)
Res.push_back("-disable-llvm-verifier");
}
@@ -789,6 +791,7 @@ static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
Opts.SoftFloat = Args.hasArg(OPT_msoft_float);
Opts.UnwindTables = Args.hasArg(OPT_munwind_tables);
Opts.RelocationModel = getLastArgValue(Args, OPT_mrelocation_model, "pic");
+ Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases);
Opts.MainFileName = getLastArgValue(Args, OPT_main_file_name);
Opts.VerifyModule = !Args.hasArg(OPT_disable_llvm_verifier);
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index 1c958a7..1e210b4 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -159,48 +159,6 @@ ASTConsumer *SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI,
return new ASTConsumer();
}
-CodeGenAction::CodeGenAction(unsigned _Act) : Act(_Act) {}
-
-ASTConsumer *CodeGenAction::CreateASTConsumer(CompilerInstance &CI,
- llvm::StringRef InFile) {
- BackendAction BA = static_cast<BackendAction>(Act);
- llvm::OwningPtr<llvm::raw_ostream> OS;
- switch (BA) {
- case Backend_EmitAssembly:
- OS.reset(CI.createDefaultOutputFile(false, InFile, "s"));
- break;
- case Backend_EmitLL:
- OS.reset(CI.createDefaultOutputFile(false, InFile, "ll"));
- break;
- case Backend_EmitBC:
- OS.reset(CI.createDefaultOutputFile(true, InFile, "bc"));
- break;
- case Backend_EmitNothing:
- break;
- case Backend_EmitObj:
- OS.reset(CI.createDefaultOutputFile(true, InFile, "o"));
- break;
- }
- if (BA != Backend_EmitNothing && !OS)
- return 0;
-
- return CreateBackendConsumer(BA, CI.getDiagnostics(), CI.getLangOpts(),
- CI.getCodeGenOpts(), CI.getTargetOpts(),
- CI.getFrontendOpts().ShowTimers, InFile,
- OS.take(), CI.getLLVMContext());
-}
-
-EmitAssemblyAction::EmitAssemblyAction()
- : CodeGenAction(Backend_EmitAssembly) {}
-
-EmitBCAction::EmitBCAction() : CodeGenAction(Backend_EmitBC) {}
-
-EmitLLVMAction::EmitLLVMAction() : CodeGenAction(Backend_EmitLL) {}
-
-EmitLLVMOnlyAction::EmitLLVMOnlyAction() : CodeGenAction(Backend_EmitNothing) {}
-
-EmitObjAction::EmitObjAction() : CodeGenAction(Backend_EmitObj) {}
-
//===----------------------------------------------------------------------===//
// Preprocessor Actions
//===----------------------------------------------------------------------===//
diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp
index 2e0b4bd..34cb9ec 100644
--- a/lib/Frontend/InitHeaderSearch.cpp
+++ b/lib/Frontend/InitHeaderSearch.cpp
@@ -489,8 +489,10 @@ void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(const llvm::Triple &tripl
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
"i686-pc-linux-gnu", "", "", triple);
// Debian sid
- AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.2",
+ AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
"x86_64-linux-gnu", "32", "", triple);
+ AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
+ "i486-linux-gnu", "64", "", triple);
// Ubuntu 7.10 - Gutsy Gibbon
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.3",
"i486-linux-gnu", "", "", triple);
diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
index b7ab3d8..8bcd3a8 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -439,6 +439,7 @@ static void InitializeFileRemapping(Diagnostic &Diags,
if (!FromFile) {
Diags.Report(diag::err_fe_remap_missing_from_file)
<< Remap->first;
+ delete Remap->second;
continue;
}
@@ -477,7 +478,7 @@ static void InitializeFileRemapping(Diagnostic &Diags,
= llvm::MemoryBuffer::getFile(ToFile->getName(), &ErrorStr);
if (!Buffer) {
Diags.Report(diag::err_fe_error_opening)
- << Remap->second << ErrorStr;
+ << Remap->second << ErrorStr;
continue;
}
diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp
index 625997c..356bd07 100644
--- a/lib/Frontend/PCHReaderDecl.cpp
+++ b/lib/Frontend/PCHReaderDecl.cpp
@@ -39,6 +39,7 @@ namespace {
void VisitDecl(Decl *D);
void VisitTranslationUnitDecl(TranslationUnitDecl *TU);
void VisitNamedDecl(NamedDecl *ND);
+ void VisitNamespaceDecl(NamespaceDecl *D);
void VisitTypeDecl(TypeDecl *TD);
void VisitTypedefDecl(TypedefDecl *TD);
void VisitTagDecl(TagDecl *TD);
@@ -96,6 +97,18 @@ void PCHDeclReader::VisitNamedDecl(NamedDecl *ND) {
ND->setDeclName(Reader.ReadDeclarationName(Record, Idx));
}
+void PCHDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {
+ VisitNamedDecl(D);
+ D->setLBracLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ D->setRBracLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ D->setNextNamespace(
+ cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
+ D->setOriginalNamespace(
+ cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
+ D->setAnonymousNamespace(
+ cast_or_null<NamespaceDecl>(Reader.GetDecl(Record[Idx++])));
+}
+
void PCHDeclReader::VisitTypeDecl(TypeDecl *TD) {
VisitNamedDecl(TD);
TD->setTypeForDecl(Reader.GetType(Record[Idx++]).getTypePtr());
@@ -235,7 +248,6 @@ void PCHDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
IVars.reserve(NumIvars);
for (unsigned I = 0; I != NumIvars; ++I)
IVars.push_back(cast<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])));
- ID->setIVarList(IVars.data(), NumIvars, *Reader.getContext());
ID->setCategoryList(
cast_or_null<ObjCCategoryDecl>(Reader.GetDecl(Record[Idx++])));
ID->setForwardDecl(Record[Idx++]);
@@ -517,6 +529,10 @@ Attr *PCHReader::ReadAttributes() {
SIMPLE_ATTR(GNUInline);
SIMPLE_ATTR(Hiding);
+ case Attr::IBActionKind:
+ New = ::new (*Context) IBActionAttr();
+ break;
+
case Attr::IBOutletKind:
New = ::new (*Context) IBOutletAttr();
break;
@@ -546,7 +562,9 @@ Attr *PCHReader::ReadAttributes() {
SIMPLE_ATTR(ObjCException);
SIMPLE_ATTR(ObjCNSObject);
+ SIMPLE_ATTR(CFReturnsNotRetained);
SIMPLE_ATTR(CFReturnsRetained);
+ SIMPLE_ATTR(NSReturnsNotRetained);
SIMPLE_ATTR(NSReturnsRetained);
SIMPLE_ATTR(Overloadable);
SIMPLE_ATTR(Override);
@@ -568,6 +586,7 @@ Attr *PCHReader::ReadAttributes() {
SIMPLE_ATTR(WarnUnusedResult);
SIMPLE_ATTR(Weak);
+ SIMPLE_ATTR(WeakRef);
SIMPLE_ATTR(WeakImport);
}
@@ -738,6 +757,10 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
case pch::DECL_BLOCK:
D = BlockDecl::Create(*Context, 0, SourceLocation());
break;
+
+ case pch::DECL_NAMESPACE:
+ D = NamespaceDecl::Create(*Context, 0, SourceLocation(), 0);
+ break;
}
assert(D && "Unknown declaration reading PCH file");
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index 4c99dbe..93af754 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -1852,12 +1852,13 @@ void PCHWriter::WriteAttributeRecord(const Attr *Attr) {
case Attr::GNUInline:
case Attr::Hiding:
+ case Attr::IBActionKind:
case Attr::IBOutletKind:
case Attr::Malloc:
case Attr::NoDebug:
+ case Attr::NoInline:
case Attr::NoReturn:
case Attr::NoThrow:
- case Attr::NoInline:
break;
case Attr::NonNull: {
@@ -1867,10 +1868,12 @@ void PCHWriter::WriteAttributeRecord(const Attr *Attr) {
break;
}
- case Attr::ObjCException:
- case Attr::ObjCNSObject:
+ case Attr::CFReturnsNotRetained:
case Attr::CFReturnsRetained:
+ case Attr::NSReturnsNotRetained:
case Attr::NSReturnsRetained:
+ case Attr::ObjCException:
+ case Attr::ObjCNSObject:
case Attr::Overloadable:
case Attr::Override:
break;
@@ -1913,6 +1916,7 @@ void PCHWriter::WriteAttributeRecord(const Attr *Attr) {
case Attr::WarnUnusedResult:
case Attr::Weak:
+ case Attr::WeakRef:
case Attr::WeakImport:
break;
}
@@ -2332,4 +2336,3 @@ void PCHWriter::AddDeclarationName(DeclarationName Name, RecordData &Record) {
break;
}
}
-
diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp
index d105382..e776d32 100644
--- a/lib/Frontend/PCHWriterDecl.cpp
+++ b/lib/Frontend/PCHWriterDecl.cpp
@@ -42,6 +42,7 @@ namespace {
void VisitDecl(Decl *D);
void VisitTranslationUnitDecl(TranslationUnitDecl *D);
void VisitNamedDecl(NamedDecl *D);
+ void VisitNamespaceDecl(NamespaceDecl *D);
void VisitTypeDecl(TypeDecl *D);
void VisitTypedefDecl(TypedefDecl *D);
void VisitTagDecl(TagDecl *D);
@@ -99,6 +100,16 @@ void PCHDeclWriter::VisitNamedDecl(NamedDecl *D) {
Writer.AddDeclarationName(D->getDeclName(), Record);
}
+void PCHDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) {
+ VisitNamedDecl(D);
+ Writer.AddSourceLocation(D->getLBracLoc(), Record);
+ Writer.AddSourceLocation(D->getRBracLoc(), Record);
+ Writer.AddDeclRef(D->getNextNamespace(), Record);
+ Writer.AddDeclRef(D->getOriginalNamespace(), Record);
+ Writer.AddDeclRef(D->getAnonymousNamespace(), Record);
+ Code = pch::DECL_NAMESPACE;
+}
+
void PCHDeclWriter::VisitTypeDecl(TypeDecl *D) {
VisitNamedDecl(D);
Writer.AddTypeRef(QualType(D->getTypeForDecl(), 0), Record);
diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp
index 43deaee..774372c 100644
--- a/lib/Frontend/PrintPreprocessedOutput.cpp
+++ b/lib/Frontend/PrintPreprocessedOutput.cpp
@@ -67,12 +67,7 @@ static void PrintMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI,
if (I->hasLeadingSpace())
OS << ' ';
- // Make sure we have enough space in the spelling buffer.
- if (I->getLength() > SpellingBuffer.size())
- SpellingBuffer.resize(I->getLength());
- const char *Buffer = SpellingBuffer.data();
- unsigned SpellingLen = PP.getSpelling(*I, Buffer);
- OS.write(Buffer, SpellingLen);
+ OS << PP.getSpelling(*I, SpellingBuffer);
}
}
diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp
index 9dade66..a13bccb 100644
--- a/lib/Frontend/RewriteObjC.cpp
+++ b/lib/Frontend/RewriteObjC.cpp
@@ -26,6 +26,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/DenseSet.h"
+
using namespace clang;
using llvm::utostr;
@@ -120,8 +121,10 @@ namespace {
// Block expressions.
llvm::SmallVector<BlockExpr *, 32> Blocks;
+ llvm::SmallVector<int, 32> InnerDeclRefsCount;
+ llvm::SmallVector<BlockDeclRefExpr *, 32> InnerDeclRefs;
+
llvm::SmallVector<BlockDeclRefExpr *, 32> BlockDeclRefs;
- llvm::DenseMap<BlockDeclRefExpr *, CallExpr *> BlockCallExprs;
// Block related declarations.
llvm::SmallVector<ValueDecl *, 8> BlockByCopyDecls;
@@ -253,6 +256,8 @@ namespace {
void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl);
void RewriteImplementationDecl(Decl *Dcl);
void RewriteObjCMethodDecl(ObjCMethodDecl *MDecl, std::string &ResultStr);
+ void RewriteTypeIntoString(QualType T, std::string &ResultStr,
+ const FunctionType *&FPRetType);
void RewriteByRefString(std::string &ResultStr, const std::string &Name,
ValueDecl *VD);
void RewriteCategoryDecl(ObjCCategoryDecl *Dcl);
@@ -301,8 +306,12 @@ namespace {
Stmt *RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
SourceLocation OrigEnd);
CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD,
- Expr **args, unsigned nargs);
- Stmt *SynthMessageExpr(ObjCMessageExpr *Exp);
+ Expr **args, unsigned nargs,
+ SourceLocation StartLoc=SourceLocation(),
+ SourceLocation EndLoc=SourceLocation());
+ Stmt *SynthMessageExpr(ObjCMessageExpr *Exp,
+ SourceLocation StartLoc=SourceLocation(),
+ SourceLocation EndLoc=SourceLocation());
Stmt *RewriteBreakStmt(BreakStmt *S);
Stmt *RewriteContinueStmt(ContinueStmt *S);
void SynthCountByEnumWithState(std::string &buf);
@@ -342,7 +351,7 @@ namespace {
std::string &Result);
void SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl,
std::string &Result);
- void SynthesizeIvarOffsetComputation(ObjCImplementationDecl *IDecl,
+ void SynthesizeIvarOffsetComputation(ObjCContainerDecl *IDecl,
ObjCIvarDecl *ivar,
std::string &Result);
void RewriteImplementations();
@@ -379,8 +388,10 @@ namespace {
void RewriteRecordBody(RecordDecl *RD);
void CollectBlockDeclRefInfo(BlockExpr *Exp);
- void GetBlockCallExprs(Stmt *S);
void GetBlockDeclRefExprs(Stmt *S);
+ void GetInnerBlockDeclRefExprs(Stmt *S,
+ llvm::SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs,
+ llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts);
// We avoid calling Type::isBlockPointerType(), since it operates on the
// canonical type. We only care if the top-level type is a closure pointer.
@@ -412,7 +423,8 @@ namespace {
void RewriteCastExpr(CStyleCastExpr *CE);
FunctionDecl *SynthBlockInitFunctionDecl(const char *name);
- Stmt *SynthBlockInitExpr(BlockExpr *Exp);
+ Stmt *SynthBlockInitExpr(BlockExpr *Exp,
+ const llvm::SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs);
void QuoteDoublequotes(std::string &From, std::string &To) {
for (unsigned i = 0; i < From.length(); i++) {
@@ -547,7 +559,7 @@ void RewriteObjC::Initialize(ASTContext &context) {
Preamble += "#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
Preamble += "#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
} else
- Preamble += "#define __OBJC_RW_DLLIMPORT extern\n";
+ Preamble += "#define __OBJC_RW_DLLIMPORT extern\n";
Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSend";
Preamble += "(struct objc_object *, struct objc_selector *, ...);\n";
Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSendSuper";
@@ -606,7 +618,8 @@ void RewriteObjC::Initialize(ASTContext &context) {
Preamble += "};\n";
Preamble += "// Runtime copy/destroy helper functions (from Block_private.h)\n";
Preamble += "#ifdef __OBJC_EXPORT_BLOCKS\n";
- Preamble += "extern \"C\" __declspec(dllexport) void _Block_object_assign(void *, const void *, const int);\n";
+ Preamble += "extern \"C\" __declspec(dllexport) "
+ "void _Block_object_assign(void *, const void *, const int);\n";
Preamble += "extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
@@ -627,6 +640,9 @@ void RewriteObjC::Initialize(ASTContext &context) {
Preamble += "#define __block\n";
Preamble += "#define __weak\n";
}
+ // NOTE! Windows uses LLP64 for 64bit mode. So, cast pointer to long long
+ // as this avoids warning in any 64bit/32bit compilation model.
+ Preamble += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
}
@@ -750,6 +766,8 @@ static std::string getIvarAccessString(ObjCInterfaceDecl *ClassDecl,
void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
ObjCImplementationDecl *IMD,
ObjCCategoryImplDecl *CID) {
+ static bool objcGetPropertyDefined = false;
+ static bool objcSetPropertyDefined = false;
SourceLocation startLoc = PID->getLocStart();
InsertText(startLoc, "// ");
const char *startBuf = SM->getCharacterData(startLoc);
@@ -769,15 +787,55 @@ void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
if (!OID)
return;
-
+ unsigned Attributes = PD->getPropertyAttributes();
+ bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) &&
+ (Attributes & (ObjCPropertyDecl::OBJC_PR_retain |
+ ObjCPropertyDecl::OBJC_PR_copy));
std::string Getr;
+ if (GenGetProperty && !objcGetPropertyDefined) {
+ objcGetPropertyDefined = true;
+ // FIXME. Is this attribute correct in all cases?
+ Getr = "\nextern \"C\" __declspec(dllimport) "
+ "id objc_getProperty(id, SEL, long, bool);\n";
+ }
RewriteObjCMethodDecl(PD->getGetterMethodDecl(), Getr);
Getr += "{ ";
// Synthesize an explicit cast to gain access to the ivar.
- // FIXME: deal with code generation implications for various property
- // attributes (copy, retain, nonatomic).
// See objc-act.c:objc_synthesize_new_getter() for details.
- Getr += "return " + getIvarAccessString(ClassDecl, OID);
+ if (GenGetProperty) {
+ // return objc_getProperty(self, _cmd, offsetof(ClassDecl, OID), 1)
+ Getr += "typedef ";
+ const FunctionType *FPRetType = 0;
+ RewriteTypeIntoString(PD->getGetterMethodDecl()->getResultType(), Getr,
+ FPRetType);
+ Getr += " _TYPE";
+ if (FPRetType) {
+ Getr += ")"; // close the precedence "scope" for "*".
+
+ // Now, emit the argument types (if any).
+ if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)) {
+ Getr += "(";
+ for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) {
+ if (i) Getr += ", ";
+ std::string ParamStr = FT->getArgType(i).getAsString();
+ Getr += ParamStr;
+ }
+ if (FT->isVariadic()) {
+ if (FT->getNumArgs()) Getr += ", ";
+ Getr += "...";
+ }
+ Getr += ")";
+ } else
+ Getr += "()";
+ }
+ Getr += ";\n";
+ Getr += "return (_TYPE)";
+ Getr += "objc_getProperty(self, _cmd, ";
+ SynthesizeIvarOffsetComputation(ClassDecl, OID, Getr);
+ Getr += ", 1)";
+ }
+ else
+ Getr += "return " + getIvarAccessString(ClassDecl, OID);
Getr += "; }";
InsertText(onePastSemiLoc, Getr);
if (PD->isReadOnly())
@@ -785,14 +843,38 @@ void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
// Generate the 'setter' function.
std::string Setr;
+ bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain |
+ ObjCPropertyDecl::OBJC_PR_copy);
+ if (GenSetProperty && !objcSetPropertyDefined) {
+ objcSetPropertyDefined = true;
+ // FIXME. Is this attribute correct in all cases?
+ Setr = "\nextern \"C\" __declspec(dllimport) "
+ "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
+ }
+
RewriteObjCMethodDecl(PD->getSetterMethodDecl(), Setr);
Setr += "{ ";
// Synthesize an explicit cast to initialize the ivar.
- // FIXME: deal with code generation implications for various property
- // attributes (copy, retain, nonatomic).
// See objc-act.c:objc_synthesize_new_setter() for details.
- Setr += getIvarAccessString(ClassDecl, OID) + " = ";
- Setr += PD->getNameAsCString();
+ if (GenSetProperty) {
+ Setr += "objc_setProperty (self, _cmd, ";
+ SynthesizeIvarOffsetComputation(ClassDecl, OID, Setr);
+ Setr += ", (id)";
+ Setr += PD->getNameAsCString();
+ Setr += ", ";
+ if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic)
+ Setr += "0, ";
+ else
+ Setr += "1, ";
+ if (Attributes & ObjCPropertyDecl::OBJC_PR_copy)
+ Setr += "1)";
+ else
+ Setr += "0)";
+ }
+ else {
+ Setr += getIvarAccessString(ClassDecl, OID) + " = ";
+ Setr += PD->getNameAsCString();
+ }
Setr += "; }";
InsertText(onePastSemiLoc, Setr);
}
@@ -929,18 +1011,15 @@ void RewriteObjC::RewriteForwardProtocolDecl(ObjCForwardProtocolDecl *PDecl) {
ReplaceText(LocStart, 0, "// ");
}
-void RewriteObjC::RewriteObjCMethodDecl(ObjCMethodDecl *OMD,
- std::string &ResultStr) {
- //fprintf(stderr,"In RewriteObjCMethodDecl\n");
- const FunctionType *FPRetType = 0;
- ResultStr += "\nstatic ";
- if (OMD->getResultType()->isObjCQualifiedIdType())
+void RewriteObjC::RewriteTypeIntoString(QualType T, std::string &ResultStr,
+ const FunctionType *&FPRetType) {
+ if (T->isObjCQualifiedIdType())
ResultStr += "id";
- else if (OMD->getResultType()->isFunctionPointerType() ||
- OMD->getResultType()->isBlockPointerType()) {
+ else if (T->isFunctionPointerType() ||
+ T->isBlockPointerType()) {
// needs special handling, since pointer-to-functions have special
// syntax (where a decaration models use).
- QualType retType = OMD->getResultType();
+ QualType retType = T;
QualType PointeeTy;
if (const PointerType* PT = retType->getAs<PointerType>())
PointeeTy = PT->getPointeeType();
@@ -951,7 +1030,15 @@ void RewriteObjC::RewriteObjCMethodDecl(ObjCMethodDecl *OMD,
ResultStr += "(*";
}
} else
- ResultStr += OMD->getResultType().getAsString();
+ ResultStr += T.getAsString();
+}
+
+void RewriteObjC::RewriteObjCMethodDecl(ObjCMethodDecl *OMD,
+ std::string &ResultStr) {
+ //fprintf(stderr,"In RewriteObjCMethodDecl\n");
+ const FunctionType *FPRetType = 0;
+ ResultStr += "\nstatic ";
+ RewriteTypeIntoString(OMD->getResultType(), ResultStr, FPRetType);
ResultStr += " ";
// Unique method name
@@ -1952,7 +2039,8 @@ Stmt *RewriteObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) {
}
CallExpr *RewriteObjC::SynthesizeCallToFunctionDecl(
- FunctionDecl *FD, Expr **args, unsigned nargs) {
+ FunctionDecl *FD, Expr **args, unsigned nargs, SourceLocation StartLoc,
+ SourceLocation EndLoc) {
// Get the type, we will need to reference it in a couple spots.
QualType msgSendType = FD->getType();
@@ -1968,8 +2056,10 @@ CallExpr *RewriteObjC::SynthesizeCallToFunctionDecl(
const FunctionType *FT = msgSendType->getAs<FunctionType>();
- return new (Context) CallExpr(*Context, ICE, args, nargs, FT->getResultType(),
- SourceLocation());
+ CallExpr *Exp =
+ new (Context) CallExpr(*Context, ICE, args, nargs, FT->getResultType(),
+ EndLoc);
+ return Exp;
}
static bool scanForProtocolRefs(const char *startBuf, const char *endBuf,
@@ -2165,8 +2255,10 @@ void RewriteObjC::SynthSelGetUidFunctionDecl() {
llvm::SmallVector<QualType, 16> ArgTys;
ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
QualType getFuncType = Context->getFunctionType(Context->getObjCSelType(),
- &ArgTys[0], ArgTys.size(),
- false /*isVariadic*/, 0);
+ &ArgTys[0], ArgTys.size(),
+ false /*isVariadic*/, 0,
+ false, false, 0, 0, false,
+ CC_Default);
SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
SelGetUidIdent, getFuncType, 0,
@@ -2196,6 +2288,36 @@ static void RewriteBlockPointerType(std::string& Str, QualType Type) {
}
}
+// FIXME. Consolidate this routine with RewriteBlockPointerType.
+static void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD) {
+ QualType Type = VD->getType();
+ std::string TypeString(Type.getAsString());
+ const char *argPtr = TypeString.c_str();
+ int paren = 0;
+ while (*argPtr) {
+ switch (*argPtr) {
+ case '(':
+ Str += *argPtr;
+ paren++;
+ break;
+ case ')':
+ Str += *argPtr;
+ paren--;
+ break;
+ case '^':
+ Str += '*';
+ if (paren == 1)
+ Str += VD->getNameAsString();
+ break;
+ default:
+ Str += *argPtr;
+ break;
+ }
+ argPtr++;
+ }
+}
+
+
void RewriteObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) {
SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
const FunctionType *funcType = FD->getType()->getAs<FunctionType>();
@@ -2231,7 +2353,9 @@ void RewriteObjC::SynthSuperContructorFunctionDecl() {
ArgTys.push_back(argT);
QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
&ArgTys[0], ArgTys.size(),
- false, 0);
+ false, 0,
+ false, false, 0, 0, false,
+ CC_Default);
SuperContructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
msgSendIdent, msgSendType, 0,
@@ -2250,7 +2374,9 @@ void RewriteObjC::SynthMsgSendFunctionDecl() {
ArgTys.push_back(argT);
QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
&ArgTys[0], ArgTys.size(),
- true /*isVariadic*/, 0);
+ true /*isVariadic*/, 0,
+ false, false, 0, 0, false,
+ CC_Default);
MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
msgSendIdent, msgSendType, 0,
@@ -2272,7 +2398,9 @@ void RewriteObjC::SynthMsgSendSuperFunctionDecl() {
ArgTys.push_back(argT);
QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
&ArgTys[0], ArgTys.size(),
- true /*isVariadic*/, 0);
+ true /*isVariadic*/, 0,
+ false, false, 0, 0, false,
+ CC_Default);
MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
msgSendIdent, msgSendType, 0,
@@ -2291,7 +2419,9 @@ void RewriteObjC::SynthMsgSendStretFunctionDecl() {
ArgTys.push_back(argT);
QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
&ArgTys[0], ArgTys.size(),
- true /*isVariadic*/, 0);
+ true /*isVariadic*/, 0,
+ false, false, 0, 0, false,
+ CC_Default);
MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
msgSendIdent, msgSendType, 0,
@@ -2315,7 +2445,9 @@ void RewriteObjC::SynthMsgSendSuperStretFunctionDecl() {
ArgTys.push_back(argT);
QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(),
&ArgTys[0], ArgTys.size(),
- true /*isVariadic*/, 0);
+ true /*isVariadic*/, 0,
+ false, false, 0, 0, false,
+ CC_Default);
MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
msgSendIdent, msgSendType, 0,
@@ -2334,7 +2466,9 @@ void RewriteObjC::SynthMsgSendFpretFunctionDecl() {
ArgTys.push_back(argT);
QualType msgSendType = Context->getFunctionType(Context->DoubleTy,
&ArgTys[0], ArgTys.size(),
- true /*isVariadic*/, 0);
+ true /*isVariadic*/, 0,
+ false, false, 0, 0, false,
+ CC_Default);
MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
msgSendIdent, msgSendType, 0,
@@ -2348,7 +2482,9 @@ void RewriteObjC::SynthGetClassFunctionDecl() {
ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
QualType getClassType = Context->getFunctionType(Context->getObjCIdType(),
&ArgTys[0], ArgTys.size(),
- false /*isVariadic*/, 0);
+ false /*isVariadic*/, 0,
+ false, false, 0, 0, false,
+ CC_Default);
GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
getClassIdent, getClassType, 0,
@@ -2362,7 +2498,9 @@ void RewriteObjC::SynthGetMetaClassFunctionDecl() {
ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
QualType getClassType = Context->getFunctionType(Context->getObjCIdType(),
&ArgTys[0], ArgTys.size(),
- false /*isVariadic*/, 0);
+ false /*isVariadic*/, 0,
+ false, false, 0, 0, false,
+ CC_Default);
GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
getClassIdent, getClassType, 0,
@@ -2485,7 +2623,9 @@ QualType RewriteObjC::getConstantStringStructType() {
return Context->getTagDeclType(ConstantStringDecl);
}
-Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
+Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
+ SourceLocation StartLoc,
+ SourceLocation EndLoc) {
if (!SelGetUidFunctionDecl)
SynthSelGetUidFunctionDecl();
if (!MsgSendFunctionDecl)
@@ -2551,7 +2691,9 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
false, argType, SourceLocation()));
CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
&ClsExprs[0],
- ClsExprs.size());
+ ClsExprs.size(),
+ StartLoc,
+ EndLoc);
// To turn off a warning, type-cast to 'id'
InitExprs.push_back( // set 'super class', using objc_getClass().
NoTypeInfoCStyleCastExpr(Context,
@@ -2606,7 +2748,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
SourceLocation()));
CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
&ClsExprs[0],
- ClsExprs.size());
+ ClsExprs.size(),
+ StartLoc, EndLoc);
MsgExprs.push_back(Cls);
}
} else { // instance message.
@@ -2636,7 +2779,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
false, argType, SourceLocation()));
CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
&ClsExprs[0],
- ClsExprs.size());
+ ClsExprs.size(),
+ StartLoc, EndLoc);
// To turn off a warning, type-cast to 'id'
InitExprs.push_back(
// set 'super class', using objc_getClass().
@@ -2695,7 +2839,9 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
Exp->getSelector().getAsString().size(),
false, argType, SourceLocation()));
CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
- &SelExprs[0], SelExprs.size());
+ &SelExprs[0], SelExprs.size(),
+ StartLoc,
+ EndLoc);
MsgExprs.push_back(SelExp);
// Now push any user supplied arguments.
@@ -2752,6 +2898,10 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
}
returnType = OMD->getResultType()->isObjCQualifiedIdType()
? Context->getObjCIdType() : OMD->getResultType();
+ if (isTopLevelBlockPointerType(returnType)) {
+ const BlockPointerType *BPT = returnType->getAs<BlockPointerType>();
+ returnType = Context->getPointerType(BPT->getPointeeType());
+ }
} else {
returnType = Context->getObjCIdType();
}
@@ -2774,18 +2924,20 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
QualType castType = Context->getFunctionType(returnType,
&ArgTypes[0], ArgTypes.size(),
// If we don't have a method decl, force a variadic cast.
- Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : true, 0);
+ Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : true, 0,
+ false, false, 0, 0, false,
+ CC_Default);
castType = Context->getPointerType(castType);
cast = NoTypeInfoCStyleCastExpr(Context, castType, CastExpr::CK_Unknown,
cast);
// Don't forget the parens to enforce the proper binding.
- ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), cast);
+ ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
const FunctionType *FT = msgSendType->getAs<FunctionType>();
CallExpr *CE = new (Context) CallExpr(*Context, PE, &MsgExprs[0],
MsgExprs.size(),
- FT->getResultType(), SourceLocation());
+ FT->getResultType(), EndLoc);
Stmt *ReplacingStmt = CE;
if (MsgSendStretFlavor) {
// We have the method which returns a struct/union. Must also generate
@@ -2803,7 +2955,9 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
// Now do the "normal" pointer to function cast.
castType = Context->getFunctionType(returnType,
&ArgTypes[0], ArgTypes.size(),
- Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : false, 0);
+ Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : false, 0,
+ false, false, 0, 0, false,
+ CC_Default);
castType = Context->getPointerType(castType);
cast = NoTypeInfoCStyleCastExpr(Context, castType, CastExpr::CK_Unknown,
cast);
@@ -2846,7 +3000,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
}
Stmt *RewriteObjC::RewriteMessageExpr(ObjCMessageExpr *Exp) {
- Stmt *ReplacingStmt = SynthMessageExpr(Exp);
+ Stmt *ReplacingStmt = SynthMessageExpr(Exp, Exp->getLocStart(),
+ Exp->getLocEnd());
// Now do the actual rewrite.
ReplaceStmt(Exp, ReplacingStmt);
@@ -3430,7 +3585,7 @@ void RewriteObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
/// SynthesizeIvarOffsetComputation - This rutine synthesizes computation of
/// ivar offset.
-void RewriteObjC::SynthesizeIvarOffsetComputation(ObjCImplementationDecl *IDecl,
+void RewriteObjC::SynthesizeIvarOffsetComputation(ObjCContainerDecl *IDecl,
ObjCIvarDecl *ivar,
std::string &Result) {
if (ivar->isBitField()) {
@@ -3504,12 +3659,12 @@ void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
ObjCInterfaceDecl::ivar_iterator IVI, IVE;
llvm::SmallVector<ObjCIvarDecl *, 8> IVars;
if (!IDecl->ivar_empty()) {
- for (ObjCImplementationDecl::ivar_iterator
+ for (ObjCInterfaceDecl::ivar_iterator
IV = IDecl->ivar_begin(), IVEnd = IDecl->ivar_end();
IV != IVEnd; ++IV)
IVars.push_back(*IV);
- IVI = IVars.begin();
- IVE = IVars.end();
+ IVI = IDecl->ivar_begin();
+ IVE = IDecl->ivar_end();
} else {
IVI = CDecl->ivar_begin();
IVE = CDecl->ivar_end();
@@ -3728,9 +3883,7 @@ void RewriteObjC::RewriteImplementations() {
void RewriteObjC::SynthesizeMetaDataIntoBuffer(std::string &Result) {
int ClsDefCount = ClassImplementation.size();
int CatDefCount = CategoryImplementation.size();
-
- // This is needed for determining instance variable offsets.
- Result += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long) &((TYPE *)0)->MEMBER)\n";
+
// For each implemented class, write out all its meta data.
for (int i = 0; i < ClsDefCount; i++)
RewriteObjCClassMetaData(ClassImplementation[i], Result);
@@ -3888,7 +4041,6 @@ std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i,
for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
E = BlockByCopyDecls.end(); I != E; ++I) {
S += " ";
- std::string Name = (*I)->getNameAsString();
// Handle nested closure invocation. For example:
//
// void (^myImportedClosure)(void);
@@ -3899,11 +4051,19 @@ std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i,
// myImportedClosure(); // import and invoke the closure
// };
//
- if (isTopLevelBlockPointerType((*I)->getType()))
- S += "struct __block_impl *";
- else
+ if (isTopLevelBlockPointerType((*I)->getType())) {
+ RewriteBlockPointerTypeVariable(S, (*I));
+ S += " = (";
+ RewriteBlockPointerType(S, (*I)->getType());
+ S += ")";
+ S += "__cself->" + (*I)->getNameAsString() + "; // bound by copy\n";
+ }
+ else {
+ std::string Name = (*I)->getNameAsString();
(*I)->getType().getAsStringInternal(Name, Context->PrintingPolicy);
- S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by copy\n";
+ S += Name + " = __cself->" +
+ (*I)->getNameAsString() + "; // bound by copy\n";
+ }
}
std::string RewrittenStr = RewrittenBlockExprs[CE];
const char *cstr = RewrittenStr.c_str();
@@ -4107,9 +4267,23 @@ void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
if (CurFunctionDeclToDeclareForBlock && !Blocks.empty())
RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock);
// Insert closures that were part of the function.
- for (unsigned i = 0; i < Blocks.size(); i++) {
-
+ for (unsigned i = 0, count=0; i < Blocks.size(); i++) {
CollectBlockDeclRefInfo(Blocks[i]);
+ // Need to copy-in the inner copied-in variables not actually used in this
+ // block.
+ for (int j = 0; j < InnerDeclRefsCount[i]; j++) {
+ BlockDeclRefExpr *Exp = InnerDeclRefs[count++];
+ ValueDecl *VD = Exp->getDecl();
+ BlockDeclRefs.push_back(Exp);
+ if (!Exp->isByRef() && !BlockByCopyDeclsPtrSet.count(VD)) {
+ BlockByCopyDeclsPtrSet.insert(VD);
+ BlockByCopyDecls.push_back(VD);
+ }
+ if (Exp->isByRef() && !BlockByRefDeclsPtrSet.count(VD)) {
+ BlockByRefDeclsPtrSet.insert(VD);
+ BlockByRefDecls.push_back(VD);
+ }
+ }
std::string ImplTag = "__" + std::string(FunName) + "_block_impl_" + utostr(i);
std::string DescTag = "__" + std::string(FunName) + "_block_desc_" + utostr(i);
@@ -4135,10 +4309,11 @@ void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
BlockByRefDeclsPtrSet.clear();
BlockByCopyDecls.clear();
BlockByCopyDeclsPtrSet.clear();
- BlockCallExprs.clear();
ImportedBlockDecls.clear();
}
Blocks.clear();
+ InnerDeclRefsCount.clear();
+ InnerDeclRefs.clear();
RewrittenBlockExprs.clear();
}
@@ -4186,21 +4361,30 @@ void RewriteObjC::GetBlockDeclRefExprs(Stmt *S) {
return;
}
-void RewriteObjC::GetBlockCallExprs(Stmt *S) {
+void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt *S,
+ llvm::SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs,
+ llvm::SmallPtrSet<const DeclContext *, 8> &InnerContexts) {
for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
CI != E; ++CI)
if (*CI) {
- if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI))
- GetBlockCallExprs(CBE->getBody());
+ if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) {
+ InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl()));
+ GetInnerBlockDeclRefExprs(CBE->getBody(),
+ InnerBlockDeclRefs,
+ InnerContexts);
+ }
else
- GetBlockCallExprs(*CI);
- }
+ GetInnerBlockDeclRefExprs(*CI,
+ InnerBlockDeclRefs,
+ InnerContexts);
- if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
- if (CE->getCallee()->getType()->isBlockPointerType()) {
- BlockCallExprs[dyn_cast<BlockDeclRefExpr>(CE->getCallee())] = CE;
}
- }
+ // Handle specific things.
+ if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(S))
+ if (!isa<FunctionDecl>(CDRE->getDecl()) &&
+ !InnerContexts.count(CDRE->getDecl()->getDeclContext()))
+ InnerBlockDeclRefs.push_back(CDRE);
+
return;
}
@@ -4269,7 +4453,9 @@ Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) {
}
// Now do the pointer to function cast.
QualType PtrToFuncCastType = Context->getFunctionType(Exp->getType(),
- &ArgTypes[0], ArgTypes.size(), false/*no variadic*/, 0);
+ &ArgTypes[0], ArgTypes.size(), false/*no variadic*/, 0,
+ false, false, 0, 0,
+ false, CC_Default);
PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType);
@@ -4379,7 +4565,7 @@ void RewriteObjC::RewriteCastExpr(CStyleCastExpr *CE) {
const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
std::string TypeAsString = "(";
- TypeAsString += QT.getAsString();
+ RewriteBlockPointerType(TypeAsString, QT);
TypeAsString += ")";
ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
return;
@@ -4605,6 +4791,10 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) {
int flag = 0;
int isa = 0;
SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
+ if (DeclLoc.isInvalid())
+ // If type location is missing, it is because of missing type (a warning).
+ // Use variable's location which is good for this case.
+ DeclLoc = ND->getLocation();
const char *startBuf = SM->getCharacterData(DeclLoc);
SourceLocation X = ND->getLocEnd();
X = SM->getInstantiationLoc(X);
@@ -4758,10 +4948,8 @@ void RewriteObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) {
for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
if (BlockDeclRefs[i]->isByRef() ||
BlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
- BlockDeclRefs[i]->getType()->isBlockPointerType()) {
- GetBlockCallExprs(BlockDeclRefs[i]);
+ BlockDeclRefs[i]->getType()->isBlockPointerType())
ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
- }
}
}
@@ -4773,10 +4961,43 @@ FunctionDecl *RewriteObjC::SynthBlockInitFunctionDecl(const char *name) {
false);
}
-Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp) {
+Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
+ const llvm::SmallVector<BlockDeclRefExpr *, 8> &InnerBlockDeclRefs) {
Blocks.push_back(Exp);
CollectBlockDeclRefInfo(Exp);
+
+ // Add inner imported variables now used in current block.
+ int countOfInnerDecls = 0;
+ if (!InnerBlockDeclRefs.empty()) {
+ for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
+ BlockDeclRefExpr *Exp = InnerBlockDeclRefs[i];
+ ValueDecl *VD = Exp->getDecl();
+ if (!Exp->isByRef() && !BlockByCopyDeclsPtrSet.count(VD)) {
+ // We need to save the copied-in variables in nested
+ // blocks because it is needed at the end for some of the API generations.
+ // See SynthesizeBlockLiterals routine.
+ InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
+ BlockDeclRefs.push_back(Exp);
+ BlockByCopyDeclsPtrSet.insert(VD);
+ BlockByCopyDecls.push_back(VD);
+ }
+ if (Exp->isByRef() && !BlockByRefDeclsPtrSet.count(VD)) {
+ InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
+ BlockDeclRefs.push_back(Exp);
+ BlockByRefDeclsPtrSet.insert(VD);
+ BlockByRefDecls.push_back(VD);
+ }
+ }
+ // Find any imported blocks...they will need special attention.
+ for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
+ if (InnerBlockDeclRefs[i]->isByRef() ||
+ InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() ||
+ InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
+ ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
+ }
+ InnerDeclRefsCount.push_back(countOfInnerDecls);
+
std::string FuncName;
if (CurFunctionDef)
@@ -4955,6 +5176,11 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
}
if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
+ llvm::SmallVector<BlockDeclRefExpr *, 8> InnerBlockDeclRefs;
+ llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
+ InnerContexts.insert(BE->getBlockDecl());
+ GetInnerBlockDeclRefExprs(BE->getBody(),
+ InnerBlockDeclRefs, InnerContexts);
// Rewrite the block body in place.
RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
@@ -4962,7 +5188,8 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
std::string Str = Rewrite.getRewrittenText(BE->getSourceRange());
RewrittenBlockExprs[BE] = Str;
- Stmt *blockTranscribed = SynthBlockInitExpr(BE);
+ Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
+
//blockTranscribed->dump();
ReplaceStmt(S, blockTranscribed);
return blockTranscribed;
@@ -5281,11 +5508,6 @@ void RewriteObjC::HandleDeclInMainFile(Decl *D) {
RewriteBlockPointerDecl(TD);
else if (TD->getUnderlyingType()->isFunctionPointerType())
CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
- else if (TD->getUnderlyingType()->isRecordType()) {
- RecordDecl *RD = TD->getUnderlyingType()->getAs<RecordType>()->getDecl();
- if (RD->isDefinition())
- RewriteRecordBody(RD);
- }
return;
}
if (RecordDecl *RD = dyn_cast<RecordDecl>(D)) {
diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp
index 9ec5ffe..d2aa548 100644
--- a/lib/Frontend/TextDiagnosticPrinter.cpp
+++ b/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -31,7 +31,7 @@ static const enum llvm::raw_ostream::Colors warningColor =
llvm::raw_ostream::MAGENTA;
static const enum llvm::raw_ostream::Colors errorColor = llvm::raw_ostream::RED;
static const enum llvm::raw_ostream::Colors fatalColor = llvm::raw_ostream::RED;
-// used for changing only the bold attribute
+// Used for changing only the bold attribute.
static const enum llvm::raw_ostream::Colors savedColor =
llvm::raw_ostream::SAVEDCOLOR;
@@ -682,6 +682,9 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level,
// file+line+column number prefix is.
uint64_t StartOfLocationInfo = OS.tell();
+ if (!Prefix.empty())
+ OS << Prefix << ": ";
+
// If the location is specified, print out a file/line/col and include trace
// if enabled.
if (Info.getLocation().isValid()) {
@@ -786,12 +789,15 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level,
llvm::SmallString<100> OutStr;
Info.FormatDiagnostic(OutStr);
- if (DiagOpts->ShowOptionNames)
+ if (DiagOpts->ShowOptionNames) {
if (const char *Opt = Diagnostic::getWarningOptionForDiag(Info.getID())) {
OutStr += " [-W";
OutStr += Opt;
OutStr += ']';
+ } else if (Diagnostic::isBuiltinExtensionDiag(Info.getID())) {
+ OutStr += " [-pedantic]";
}
+ }
if (DiagOpts->ShowColors) {
// Print warnings, errors and fatal errors in bold, no color
OpenPOWER on IntegriCloud