summaryrefslogtreecommitdiffstats
path: root/lib/Frontend
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Frontend')
-rw-r--r--lib/Frontend/ASTConsumers.cpp2
-rw-r--r--lib/Frontend/ASTMerge.cpp103
-rw-r--r--lib/Frontend/ASTUnit.cpp30
-rw-r--r--lib/Frontend/AnalysisConsumer.cpp161
-rw-r--r--lib/Frontend/Backend.cpp38
-rw-r--r--lib/Frontend/CMakeLists.txt1
-rw-r--r--lib/Frontend/CompilerInstance.cpp54
-rw-r--r--lib/Frontend/CompilerInvocation.cpp41
-rw-r--r--lib/Frontend/FrontendActions.cpp5
-rw-r--r--lib/Frontend/HTMLDiagnostics.cpp2
-rw-r--r--lib/Frontend/InitHeaderSearch.cpp10
-rw-r--r--lib/Frontend/InitPreprocessor.cpp2
-rw-r--r--lib/Frontend/Makefile1
-rw-r--r--lib/Frontend/PCHReader.cpp44
-rw-r--r--lib/Frontend/PCHReaderDecl.cpp13
-rw-r--r--lib/Frontend/PCHReaderStmt.cpp33
-rw-r--r--lib/Frontend/PCHWriter.cpp35
-rw-r--r--lib/Frontend/PCHWriterDecl.cpp1
-rw-r--r--lib/Frontend/PCHWriterStmt.cpp21
-rw-r--r--lib/Frontend/PlistDiagnostics.cpp2
-rw-r--r--lib/Frontend/PrintParserCallbacks.cpp5
-rw-r--r--lib/Frontend/RewriteObjC.cpp448
-rw-r--r--lib/Frontend/TextDiagnosticPrinter.cpp26
23 files changed, 718 insertions, 360 deletions
diff --git a/lib/Frontend/ASTConsumers.cpp b/lib/Frontend/ASTConsumers.cpp
index 33cb94e..ebbd720 100644
--- a/lib/Frontend/ASTConsumers.cpp
+++ b/lib/Frontend/ASTConsumers.cpp
@@ -564,7 +564,7 @@ public:
if (RD->isInvalidDecl())
continue;
- if (!RD->getDefinition(C))
+ if (!RD->getDefinition())
continue;
// FIXME: Do we really need to hard code this?
diff --git a/lib/Frontend/ASTMerge.cpp b/lib/Frontend/ASTMerge.cpp
new file mode 100644
index 0000000..2228ea4
--- /dev/null
+++ b/lib/Frontend/ASTMerge.cpp
@@ -0,0 +1,103 @@
+//===-- ASTMerge.cpp - AST Merging Frontent Action --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTDiagnostic.h"
+#include "clang/AST/ASTImporter.h"
+
+using namespace clang;
+
+ASTConsumer *ASTMergeAction::CreateASTConsumer(CompilerInstance &CI,
+ llvm::StringRef InFile) {
+ return AdaptedAction->CreateASTConsumer(CI, InFile);
+}
+
+bool ASTMergeAction::BeginSourceFileAction(CompilerInstance &CI,
+ llvm::StringRef Filename) {
+ // FIXME: This is a hack. We need a better way to communicate the
+ // AST file, compiler instance, and file name than member variables
+ // of FrontendAction.
+ AdaptedAction->setCurrentFile(getCurrentFile(), takeCurrentASTUnit());
+ AdaptedAction->setCompilerInstance(&CI);
+ return AdaptedAction->BeginSourceFileAction(CI, Filename);
+}
+
+void ASTMergeAction::ExecuteAction() {
+ CompilerInstance &CI = getCompilerInstance();
+ CI.getDiagnostics().getClient()->BeginSourceFile(
+ CI.getASTContext().getLangOptions());
+ CI.getDiagnostics().SetArgToStringFn(&FormatASTNodeDiagnosticArgument,
+ &CI.getASTContext());
+ for (unsigned I = 0, N = ASTFiles.size(); I != N; ++I) {
+ ASTUnit *Unit = ASTUnit::LoadFromPCHFile(ASTFiles[I], CI.getDiagnostics(),
+ false);
+ if (!Unit)
+ continue;
+
+ ASTImporter Importer(CI.getDiagnostics(),
+ CI.getASTContext(),
+ CI.getFileManager(),
+ Unit->getASTContext(),
+ Unit->getFileManager());
+
+ TranslationUnitDecl *TU = Unit->getASTContext().getTranslationUnitDecl();
+ for (DeclContext::decl_iterator D = TU->decls_begin(),
+ DEnd = TU->decls_end();
+ D != DEnd; ++D) {
+ // Don't re-import __va_list_tag, __builtin_va_list.
+ if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
+ if (IdentifierInfo *II = ND->getIdentifier())
+ if (II->isStr("__va_list_tag") || II->isStr("__builtin_va_list"))
+ continue;
+
+ Importer.Import(*D);
+ }
+
+ delete Unit;
+ }
+
+ AdaptedAction->ExecuteAction();
+ CI.getDiagnostics().getClient()->EndSourceFile();
+}
+
+void ASTMergeAction::EndSourceFileAction() {
+ return AdaptedAction->EndSourceFileAction();
+}
+
+ASTMergeAction::ASTMergeAction(FrontendAction *AdaptedAction,
+ std::string *ASTFiles, unsigned NumASTFiles)
+ : AdaptedAction(AdaptedAction), ASTFiles(ASTFiles, ASTFiles + NumASTFiles) {
+ assert(AdaptedAction && "ASTMergeAction needs an action to adapt");
+}
+
+ASTMergeAction::~ASTMergeAction() {
+ delete AdaptedAction;
+}
+
+bool ASTMergeAction::usesPreprocessorOnly() const {
+ return AdaptedAction->usesPreprocessorOnly();
+}
+
+bool ASTMergeAction::usesCompleteTranslationUnit() {
+ return AdaptedAction->usesCompleteTranslationUnit();
+}
+
+bool ASTMergeAction::hasPCHSupport() const {
+ return AdaptedAction->hasPCHSupport();
+}
+
+bool ASTMergeAction::hasASTSupport() const {
+ return AdaptedAction->hasASTSupport();
+}
+
+bool ASTMergeAction::hasCodeCompletionSupport() const {
+ return AdaptedAction->hasCodeCompletionSupport();
+}
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index 2fb47cb..a0c4889 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -98,13 +98,12 @@ const std::string &ASTUnit::getOriginalSourceFileName() {
const std::string &ASTUnit::getPCHFileName() {
assert(isMainFileAST() && "Not an ASTUnit from a PCH file!");
- return dyn_cast<PCHReader>(Ctx->getExternalSource())->getFileName();
+ return static_cast<PCHReader *>(Ctx->getExternalSource())->getFileName();
}
ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename,
Diagnostic &Diags,
bool OnlyLocalDecls,
- bool UseBumpAllocator,
RemappedFile *RemappedFiles,
unsigned NumRemappedFiles) {
llvm::OwningPtr<ASTUnit> AST(new ASTUnit(true));
@@ -184,7 +183,7 @@ ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename,
PP.getIdentifierTable(),
PP.getSelectorTable(),
PP.getBuiltinInfo(),
- /* FreeMemory = */ !UseBumpAllocator,
+ /* FreeMemory = */ false,
/* size_reserve = */0));
ASTContext &Context = *AST->Ctx.get();
@@ -230,7 +229,7 @@ public:
}
-ASTUnit *ASTUnit::LoadFromCompilerInvocation(const CompilerInvocation &CI,
+ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI,
Diagnostic &Diags,
bool OnlyLocalDecls) {
// Create the compiler instance to use for building the AST.
@@ -238,7 +237,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocation(const CompilerInvocation &CI,
llvm::OwningPtr<ASTUnit> AST;
llvm::OwningPtr<TopLevelDeclTrackerAction> Act;
- Clang.getInvocation() = CI;
+ Clang.setInvocation(CI);
Clang.setDiagnostics(&Diags);
Clang.setDiagnosticClient(Diags.getClient());
@@ -294,7 +293,9 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocation(const CompilerInvocation &CI,
Clang.takeDiagnosticClient();
Clang.takeDiagnostics();
+ Clang.takeInvocation();
+ AST->Invocation.reset(Clang.takeInvocation());
return AST.take();
error:
@@ -310,7 +311,6 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
Diagnostic &Diags,
llvm::StringRef ResourceFilesPath,
bool OnlyLocalDecls,
- bool UseBumpAllocator,
RemappedFile *RemappedFiles,
unsigned NumRemappedFiles) {
llvm::SmallVector<const char *, 16> Args;
@@ -324,6 +324,10 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
// FIXME: We shouldn't have to pass in the path info.
driver::Driver TheDriver("clang", "/", llvm::sys::getHostTriple(),
"a.out", false, Diags);
+
+ // Don't check that inputs exist, they have been remapped.
+ TheDriver.setCheckInputsExist(false);
+
llvm::OwningPtr<driver::Compilation> C(
TheDriver.BuildCompilation(Args.size(), Args.data()));
@@ -345,19 +349,19 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
}
const driver::ArgStringList &CCArgs = Cmd->getArguments();
- CompilerInvocation CI;
- CompilerInvocation::CreateFromArgs(CI, (const char**) CCArgs.data(),
+ llvm::OwningPtr<CompilerInvocation> CI(new CompilerInvocation);
+ CompilerInvocation::CreateFromArgs(*CI, (const char**) CCArgs.data(),
(const char**) CCArgs.data()+CCArgs.size(),
Diags);
// Override any files that need remapping
for (unsigned I = 0; I != NumRemappedFiles; ++I)
- CI.getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first,
- RemappedFiles[I].second);
+ CI->getPreprocessorOpts().addRemappedFile(RemappedFiles[I].first,
+ RemappedFiles[I].second);
// Override the resources path.
- CI.getHeaderSearchOpts().ResourceDir = ResourceFilesPath;
+ CI->getHeaderSearchOpts().ResourceDir = ResourceFilesPath;
- CI.getFrontendOpts().DisableFree = UseBumpAllocator;
- return LoadFromCompilerInvocation(CI, Diags, OnlyLocalDecls);
+ CI->getFrontendOpts().DisableFree = true;
+ return LoadFromCompilerInvocation(CI.take(), Diags, OnlyLocalDecls);
}
diff --git a/lib/Frontend/AnalysisConsumer.cpp b/lib/Frontend/AnalysisConsumer.cpp
index 45a3b15..d764fd0 100644
--- a/lib/Frontend/AnalysisConsumer.cpp
+++ b/lib/Frontend/AnalysisConsumer.cpp
@@ -18,14 +18,15 @@
#include "clang/AST/DeclObjC.h"
#include "clang/AST/ParentMap.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
+#include "clang/Analysis/Analyses/UninitializedValues.h"
#include "clang/Analysis/CFG.h"
-#include "clang/Analysis/LocalCheckers.h"
-#include "clang/Analysis/ManagerRegistry.h"
-#include "clang/Analysis/PathDiagnostic.h"
-#include "clang/Analysis/PathSensitive/AnalysisManager.h"
-#include "clang/Analysis/PathSensitive/BugReporter.h"
-#include "clang/Analysis/PathSensitive/GRExprEngine.h"
-#include "clang/Analysis/PathSensitive/GRTransferFuncs.h"
+#include "clang/Checker/Checkers/LocalCheckers.h"
+#include "clang/Checker/ManagerRegistry.h"
+#include "clang/Checker/BugReporter/PathDiagnostic.h"
+#include "clang/Checker/PathSensitive/AnalysisManager.h"
+#include "clang/Checker/BugReporter/BugReporter.h"
+#include "clang/Checker/PathSensitive/GRExprEngine.h"
+#include "clang/Checker/PathSensitive/GRTransferFuncs.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/PathDiagnosticClients.h"
@@ -64,13 +65,17 @@ namespace {
class AnalysisConsumer : public ASTConsumer {
public:
typedef void (*CodeAction)(AnalysisConsumer &C, AnalysisManager &M, Decl *D);
-
+ typedef void (*TUAction)(AnalysisConsumer &C, AnalysisManager &M,
+ TranslationUnitDecl &TU);
+
private:
typedef std::vector<CodeAction> Actions;
+ typedef std::vector<TUAction> TUActions;
+
Actions FunctionActions;
Actions ObjCMethodActions;
Actions ObjCImplementationActions;
- Actions TranslationUnitActions;
+ TUActions TranslationUnitActions;
public:
ASTContext* Ctx;
@@ -133,11 +138,11 @@ public:
}
}
}
-
+
void DisplayFunction(const Decl *D) {
if (!Opts.AnalyzerDisplayProgress || declDisplayed)
return;
-
+
declDisplayed = true;
SourceManager &SM = Mgr->getASTContext().getSourceManager();
PresumedLoc Loc = SM.getPresumedLoc(D->getLocation());
@@ -162,7 +167,7 @@ public:
ObjCImplementationActions.push_back(action);
}
- void addTranslationUnitAction(CodeAction action) {
+ void addTranslationUnitAction(TUAction action) {
TranslationUnitActions.push_back(action);
}
@@ -191,7 +196,7 @@ public:
namespace llvm {
template <> struct FoldingSetTrait<AnalysisConsumer::CodeAction> {
- static inline void Profile(AnalysisConsumer::CodeAction X,
+ static inline void Profile(AnalysisConsumer::CodeAction X,
FoldingSetNodeID& ID) {
ID.AddPointer(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(X)));
}
@@ -204,42 +209,30 @@ namespace llvm {
void AnalysisConsumer::HandleTopLevelSingleDecl(Decl *D) {
switch (D->getKind()) {
+ case Decl::CXXConstructor:
+ case Decl::CXXDestructor:
+ case Decl::CXXConversion:
+ case Decl::CXXMethod:
case Decl::Function: {
FunctionDecl* FD = cast<FunctionDecl>(D);
-
if (!Opts.AnalyzeSpecificFunction.empty() &&
- Opts.AnalyzeSpecificFunction != FD->getIdentifier()->getName())
- break;
+ FD->getDeclName().getAsString() != Opts.AnalyzeSpecificFunction)
+ break;
- Stmt* Body = FD->getBody();
- if (Body) HandleCode(FD, Body, FunctionActions);
+ if (Stmt *Body = FD->getBody())
+ HandleCode(FD, Body, FunctionActions);
break;
}
case Decl::ObjCMethod: {
ObjCMethodDecl* MD = cast<ObjCMethodDecl>(D);
- if (Opts.AnalyzeSpecificFunction.size() > 0 &&
+ if (!Opts.AnalyzeSpecificFunction.empty() &&
Opts.AnalyzeSpecificFunction != MD->getSelector().getAsString())
return;
- Stmt* Body = MD->getBody();
- if (Body) HandleCode(MD, Body, ObjCMethodActions);
- break;
- }
-
- case Decl::CXXConstructor:
- case Decl::CXXDestructor:
- case Decl::CXXConversion:
- case Decl::CXXMethod: {
- CXXMethodDecl *CXXMD = cast<CXXMethodDecl>(D);
-
- if (Opts.AnalyzeSpecificFunction.size() > 0 &&
- Opts.AnalyzeSpecificFunction != CXXMD->getName())
- return;
-
- Stmt *Body = CXXMD->getBody();
- if (Body) HandleCode(CXXMD, Body, FunctionActions);
+ if (Stmt* Body = MD->getBody())
+ HandleCode(MD, Body, ObjCMethodActions);
break;
}
@@ -249,30 +242,12 @@ void AnalysisConsumer::HandleTopLevelSingleDecl(Decl *D) {
}
void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
-
+
TranslationUnitDecl *TU = C.getTranslationUnitDecl();
-
- if (!TranslationUnitActions.empty()) {
- // Find the entry function definition (if any).
- FunctionDecl *FD = 0;
- // Must specify an entry function.
- if (!Opts.AnalyzeSpecificFunction.empty()) {
- for (DeclContext::decl_iterator I=TU->decls_begin(), E=TU->decls_end();
- I != E; ++I) {
- if (FunctionDecl *fd = dyn_cast<FunctionDecl>(*I))
- if (fd->isThisDeclarationADefinition() &&
- fd->getNameAsString() == Opts.AnalyzeSpecificFunction) {
- FD = fd;
- break;
- }
- }
- }
- if (FD) {
- for (Actions::iterator I = TranslationUnitActions.begin(),
- E = TranslationUnitActions.end(); I != E; ++I)
- (*I)(*this, *Mgr, FD);
- }
+ for (TUActions::iterator I = TranslationUnitActions.begin(),
+ E = TranslationUnitActions.end(); I != E; ++I) {
+ (*I)(*this, *Mgr, *TU);
}
if (!ObjCImplementationActions.empty()) {
@@ -293,7 +268,7 @@ void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
static void FindBlocks(DeclContext *D, llvm::SmallVectorImpl<Decl*> &WL) {
if (BlockDecl *BD = dyn_cast<BlockDecl>(D))
WL.push_back(BD);
-
+
for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
I!=E; ++I)
if (DeclContext *DC = dyn_cast<DeclContext>(*I))
@@ -314,14 +289,14 @@ void AnalysisConsumer::HandleCode(Decl *D, Stmt* Body, Actions& actions) {
// Clear the AnalysisManager of old AnalysisContexts.
Mgr->ClearContexts();
-
+
// Dispatch on the actions.
llvm::SmallVector<Decl*, 10> WL;
WL.push_back(D);
-
+
if (Body && Opts.AnalyzeNestedBlocks)
FindBlocks(cast<DeclContext>(D), WL);
-
+
for (Actions::iterator I = actions.begin(), E = actions.end(); I != E; ++I)
for (llvm::SmallVectorImpl<Decl*>::iterator WI=WL.begin(), WE=WL.end();
WI != WE; ++WI)
@@ -351,7 +326,7 @@ static void ActionWarnUninitVals(AnalysisConsumer &C, AnalysisManager& mgr,
static void ActionGRExprEngine(AnalysisConsumer &C, AnalysisManager& mgr,
- Decl *D,
+ Decl *D,
GRTransferFuncs* tf) {
llvm::OwningPtr<GRTransferFuncs> TF(tf);
@@ -363,18 +338,18 @@ static void ActionGRExprEngine(AnalysisConsumer &C, AnalysisManager& mgr,
// information to see if the CFG is valid.
// FIXME: Inter-procedural analysis will need to handle invalid CFGs.
if (!mgr.getLiveVariables(D))
- return;
-
+ return;
+
GRExprEngine Eng(mgr, TF.take());
-
+
if (C.Opts.EnableExperimentalInternalChecks)
RegisterExperimentalInternalChecks(Eng);
-
+
RegisterAppleChecks(Eng, *D);
-
+
if (C.Opts.EnableExperimentalChecks)
RegisterExperimentalChecks(Eng);
-
+
// Set the graph auditor.
llvm::OwningPtr<ExplodedNode::Auditor> Auditor;
if (mgr.shouldVisualizeUbigraph()) {
@@ -397,7 +372,7 @@ static void ActionGRExprEngine(AnalysisConsumer &C, AnalysisManager& mgr,
Eng.getBugReporter().FlushReports();
}
-static void ActionCheckerCFRefAux(AnalysisConsumer &C, AnalysisManager& mgr,
+static void ActionObjCMemCheckerAux(AnalysisConsumer &C, AnalysisManager& mgr,
Decl *D, bool GCEnabled) {
GRTransferFuncs* TF = MakeCFRefCountTF(mgr.getASTContext(),
@@ -407,23 +382,23 @@ static void ActionCheckerCFRefAux(AnalysisConsumer &C, AnalysisManager& mgr,
ActionGRExprEngine(C, mgr, D, TF);
}
-static void ActionCheckerCFRef(AnalysisConsumer &C, AnalysisManager& mgr,
+static void ActionObjCMemChecker(AnalysisConsumer &C, AnalysisManager& mgr,
Decl *D) {
switch (mgr.getLangOptions().getGCMode()) {
default:
assert (false && "Invalid GC mode.");
case LangOptions::NonGC:
- ActionCheckerCFRefAux(C, mgr, D, false);
+ ActionObjCMemCheckerAux(C, mgr, D, false);
break;
case LangOptions::GCOnly:
- ActionCheckerCFRefAux(C, mgr, D, true);
+ ActionObjCMemCheckerAux(C, mgr, D, true);
break;
case LangOptions::HybridGC:
- ActionCheckerCFRefAux(C, mgr, D, false);
- ActionCheckerCFRefAux(C, mgr, D, true);
+ ActionObjCMemCheckerAux(C, mgr, D, false);
+ ActionObjCMemCheckerAux(C, mgr, D, true);
break;
}
}
@@ -457,6 +432,13 @@ static void ActionSecuritySyntacticChecks(AnalysisConsumer &C,
CheckSecuritySyntaxOnly(D, BR);
}
+static void ActionLLVMConventionChecker(AnalysisConsumer &C,
+ AnalysisManager &mgr,
+ TranslationUnitDecl &TU) {
+ BugReporter BR(mgr);
+ CheckLLVMConventions(TU, BR);
+}
+
static void ActionWarnObjCDealloc(AnalysisConsumer &C, AnalysisManager& mgr,
Decl *D) {
if (mgr.getLangOptions().getGCMode() == LangOptions::GCOnly)
@@ -489,8 +471,29 @@ static void ActionWarnSizeofPointer(AnalysisConsumer &C, AnalysisManager &mgr,
}
static void ActionInlineCall(AnalysisConsumer &C, AnalysisManager &mgr,
- Decl *D) {
- // FIXME: This is largely copy of ActionGRExprEngine. Needs cleanup.
+ TranslationUnitDecl &TU) {
+
+ // Find the entry function definition (if any).
+ FunctionDecl *D = 0;
+
+ // Must specify an entry function.
+ if (!C.Opts.AnalyzeSpecificFunction.empty()) {
+ for (DeclContext::decl_iterator I=TU.decls_begin(), E=TU.decls_end();
+ I != E; ++I) {
+ if (FunctionDecl *fd = dyn_cast<FunctionDecl>(*I))
+ if (fd->isThisDeclarationADefinition() &&
+ fd->getNameAsString() == C.Opts.AnalyzeSpecificFunction) {
+ D = fd;
+ break;
+ }
+ }
+ }
+
+ if (!D)
+ return;
+
+
+ // FIXME: This is largely copy of ActionGRExprEngine. Needs cleanup.
// Display progress.
C.DisplayFunction(D);
@@ -500,9 +503,9 @@ static void ActionInlineCall(AnalysisConsumer &C, AnalysisManager &mgr,
if (C.Opts.EnableExperimentalInternalChecks)
RegisterExperimentalInternalChecks(Eng);
-
+
RegisterAppleChecks(Eng, *D);
-
+
if (C.Opts.EnableExperimentalChecks)
RegisterExperimentalChecks(Eng);
diff --git a/lib/Frontend/Backend.cpp b/lib/Frontend/Backend.cpp
index 9be6786..f5291a9 100644
--- a/lib/Frontend/Backend.cpp
+++ b/lib/Frontend/Backend.cpp
@@ -17,7 +17,6 @@
#include "clang/CodeGen/ModuleBuilder.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "llvm/Module.h"
-#include "llvm/ModuleProvider.h"
#include "llvm/PassManager.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Assembly/PrintModulePass.h"
@@ -56,7 +55,6 @@ namespace {
llvm::Module *TheModule;
llvm::TargetData *TheTargetData;
- mutable llvm::ModuleProvider *ModuleProvider;
mutable FunctionPassManager *CodeGenPasses;
mutable PassManager *PerModulePasses;
mutable FunctionPassManager *PerFunctionPasses;
@@ -89,7 +87,7 @@ namespace {
LLVMIRGeneration("LLVM IR Generation Time"),
CodeGenerationTime("Code Generation Time"),
Gen(CreateLLVMCodeGen(Diags, infile, compopts, C)),
- TheModule(0), TheTargetData(0), ModuleProvider(0),
+ TheModule(0), TheTargetData(0),
CodeGenPasses(0), PerModulePasses(0), PerFunctionPasses(0) {
if (AsmOutStream)
@@ -101,7 +99,7 @@ namespace {
~BackendConsumer() {
delete TheTargetData;
- delete ModuleProvider;
+ delete TheModule;
delete CodeGenPasses;
delete PerModulePasses;
delete PerFunctionPasses;
@@ -116,7 +114,6 @@ namespace {
Gen->Initialize(Ctx);
TheModule = Gen->GetModule();
- ModuleProvider = new ExistingModuleProvider(TheModule);
TheTargetData = new llvm::TargetData(Ctx.Target.getTargetDescription());
if (llvm::TimePassesIsEnabled)
@@ -172,7 +169,7 @@ namespace {
FunctionPassManager *BackendConsumer::getCodeGenPasses() const {
if (!CodeGenPasses) {
- CodeGenPasses = new FunctionPassManager(ModuleProvider);
+ CodeGenPasses = new FunctionPassManager(TheModule);
CodeGenPasses->add(new TargetData(*TheTargetData));
}
@@ -190,7 +187,7 @@ PassManager *BackendConsumer::getPerModulePasses() const {
FunctionPassManager *BackendConsumer::getPerFunctionPasses() const {
if (!PerFunctionPasses) {
- PerFunctionPasses = new FunctionPassManager(ModuleProvider);
+ PerFunctionPasses = new FunctionPassManager(TheModule);
PerFunctionPasses->add(new TargetData(*TheTargetData));
}
@@ -306,20 +303,12 @@ bool BackendConsumer::AddEmitPasses() {
case 3: OptLevel = CodeGenOpt::Aggressive; break;
}
- // Normal mode, emit a .s file by running the code generator.
- // Note, this also adds codegenerator level optimization passes.
- switch (TM->addPassesToEmitFile(*PM, FormattedOutStream,
- TargetMachine::AssemblyFile, OptLevel)) {
- default:
- case FileModel::Error:
- Diags.Report(diag::err_fe_unable_to_interface_with_target);
- return false;
- case FileModel::AsmFile:
- break;
- }
-
- if (TM->addPassesToEmitFileFinish(*CodeGenPasses, (MachineCodeEmitter *)0,
- OptLevel)) {
+ // 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)) {
Diags.Report(diag::err_fe_unable_to_interface_with_target);
return false;
}
@@ -354,11 +343,11 @@ void BackendConsumer::CreatePasses() {
// Set the inline threshold following llvm-gcc.
//
// FIXME: Derive these constants in a principled fashion.
- unsigned Threshold = 200;
+ unsigned Threshold = 225;
if (CodeGenOpts.OptimizeSize)
- Threshold = 50;
+ Threshold = 75;
else if (OptLevel > 2)
- Threshold = 250;
+ Threshold = 275;
InliningPass = createFunctionInliningPass(Threshold);
break;
}
@@ -392,7 +381,6 @@ void BackendConsumer::EmitAssembly() {
if (!M) {
// The module has been released by IR gen on failures, do not
// double free.
- ModuleProvider->releaseModule();
TheModule = 0;
return;
}
diff --git a/lib/Frontend/CMakeLists.txt b/lib/Frontend/CMakeLists.txt
index 58aaa43..1d0b5c1 100644
--- a/lib/Frontend/CMakeLists.txt
+++ b/lib/Frontend/CMakeLists.txt
@@ -2,6 +2,7 @@ set(LLVM_NO_RTTI 1)
add_clang_library(clangFrontend
ASTConsumers.cpp
+ ASTMerge.cpp
ASTUnit.cpp
AnalysisConsumer.cpp
Backend.cpp
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index 19c740d..917cbd7 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -35,15 +35,19 @@
#include "llvm/System/Program.h"
using namespace clang;
-CompilerInstance::CompilerInstance(llvm::LLVMContext *_LLVMContext,
- bool _OwnsLLVMContext)
- : LLVMContext(_LLVMContext),
- OwnsLLVMContext(_OwnsLLVMContext) {
- }
+CompilerInstance::CompilerInstance()
+ : Invocation(new CompilerInvocation()) {
+}
CompilerInstance::~CompilerInstance() {
- if (OwnsLLVMContext)
- delete LLVMContext;
+}
+
+void CompilerInstance::setLLVMContext(llvm::LLVMContext *Value) {
+ LLVMContext.reset(Value);
+}
+
+void CompilerInstance::setInvocation(CompilerInvocation *Value) {
+ Invocation.reset(Value);
}
void CompilerInstance::setDiagnostics(Diagnostic *Value) {
@@ -83,6 +87,23 @@ void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) {
}
// Diagnostics
+namespace {
+ class BinaryDiagnosticSerializer : public DiagnosticClient {
+ llvm::raw_ostream &OS;
+ SourceManager *SourceMgr;
+ public:
+ explicit BinaryDiagnosticSerializer(llvm::raw_ostream &OS)
+ : OS(OS), SourceMgr(0) { }
+
+ virtual void HandleDiagnostic(Diagnostic::Level DiagLevel,
+ const DiagnosticInfo &Info);
+ };
+}
+
+void BinaryDiagnosticSerializer::HandleDiagnostic(Diagnostic::Level DiagLevel,
+ const DiagnosticInfo &Info) {
+ Info.Serialize(DiagLevel, OS);
+}
static void SetUpBuildDumpLog(const DiagnosticOptions &DiagOpts,
unsigned argc, char **argv,
@@ -122,8 +143,23 @@ Diagnostic *CompilerInstance::createDiagnostics(const DiagnosticOptions &Opts,
// Create the diagnostic client for reporting errors or for
// implementing -verify.
- llvm::OwningPtr<DiagnosticClient> DiagClient(
- new TextDiagnosticPrinter(llvm::errs(), Opts));
+ llvm::OwningPtr<DiagnosticClient> DiagClient;
+ if (Opts.BinaryOutput) {
+ if (llvm::sys::Program::ChangeStderrToBinary()) {
+ // We weren't able to set standard error to binary, which is a
+ // bit of a problem. So, just create a text diagnostic printer
+ // to complain about this problem, and pretend that the user
+ // didn't try to use binary output.
+ DiagClient.reset(new TextDiagnosticPrinter(llvm::errs(), Opts));
+ Diags->setClient(DiagClient.take());
+ Diags->Report(diag::err_fe_stderr_binary);
+ return Diags.take();
+ } else {
+ DiagClient.reset(new BinaryDiagnosticSerializer(llvm::errs()));
+ }
+ } else {
+ DiagClient.reset(new TextDiagnosticPrinter(llvm::errs(), Opts));
+ }
// Chain in -verify checker, if requested.
if (Opts.VerifyDiagnostics)
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 0bca475..a193ac8 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -170,6 +170,8 @@ static void CodeGenOptsToArgs(const CodeGenOptions &Opts,
}
if (Opts.NoZeroInitializedInBSS)
Res.push_back("-mno-zero-initialized-bss");
+ if (Opts.ObjCLegacyDispatch)
+ Res.push_back("-fobjc-legacy-dispatch");
if (Opts.SoftFloat)
Res.push_back("-msoft-float");
if (Opts.UnwindTables)
@@ -178,6 +180,8 @@ static void CodeGenOptsToArgs(const CodeGenOptions &Opts,
Res.push_back("-mrelocation-model");
Res.push_back(Opts.RelocationModel);
}
+ if (!Opts.VerifyModule)
+ Res.push_back("-disable-llvm-verifier");
}
static void DependencyOutputOptsToArgs(const DependencyOutputOptions &Opts,
@@ -220,6 +224,8 @@ static void DiagnosticOptsToArgs(const DiagnosticOptions &Opts,
Res.push_back("-fcolor-diagnostics");
if (Opts.VerifyDiagnostics)
Res.push_back("-verify");
+ if (Opts.BinaryOutput)
+ Res.push_back("-fdiagnostics-binary");
if (Opts.ShowOptionNames)
Res.push_back("-fdiagnostics-show-option");
if (Opts.TabStop != DiagnosticOptions::DefaultTabStop) {
@@ -276,6 +282,7 @@ static const char *getActionName(frontend::ActionKind Kind) {
case frontend::EmitHTML: return "-emit-html";
case frontend::EmitLLVM: return "-emit-llvm";
case frontend::EmitLLVMOnly: return "-emit-llvm-only";
+ case frontend::EmitObj: return "-emit-obj";
case frontend::FixIt: return "-fixit";
case frontend::GeneratePCH: return "-emit-pch";
case frontend::GeneratePTH: return "-emit-pth";
@@ -362,6 +369,10 @@ static void FrontendOptsToArgs(const FrontendOptions &Opts,
Res.push_back("-load");
Res.push_back(Opts.Plugins[i]);
}
+ for (unsigned i = 0, e = Opts.ASTMergeFiles.size(); i != e; ++i) {
+ Res.push_back("-ast-merge");
+ Res.push_back(Opts.ASTMergeFiles[i]);
+ }
}
static void HeaderSearchOptsToArgs(const HeaderSearchOptions &Opts,
@@ -450,6 +461,8 @@ static void LangOptsToArgs(const LangOptions &Opts,
Res.push_back("-fms-extensions");
if (Opts.ObjCNonFragileABI)
Res.push_back("-fobjc-nonfragile-abi");
+ if (Opts.ObjCNonFragileABI2)
+ Res.push_back("-fobjc-nonfragile-abi2");
// NoInline is implicit.
if (!Opts.CXXOperatorNames)
Res.push_back("-fno-operator-names");
@@ -465,6 +478,8 @@ static void LangOptsToArgs(const LangOptions &Opts,
Res.push_back("-faltivec");
if (Opts.Exceptions)
Res.push_back("-fexceptions");
+ if (Opts.SjLjExceptions)
+ Res.push_back("-fsjlj-exceptions");
if (!Opts.RTTI)
Res.push_back("-fno-rtti");
if (!Opts.NeXTRuntime)
@@ -475,8 +490,8 @@ static void LangOptsToArgs(const LangOptions &Opts,
Res.push_back("-fno-builtin");
if (!Opts.AssumeSaneOperatorNew)
Res.push_back("-fno-assume-sane-operator-new");
- if (Opts.ThreadsafeStatics)
- llvm::llvm_report_error("FIXME: Not yet implemented!");
+ if (!Opts.ThreadsafeStatics)
+ Res.push_back("-fno-threadsafe-statics");
if (Opts.POSIXThreads)
Res.push_back("-pthread");
if (Opts.Blocks)
@@ -770,18 +785,13 @@ static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
Opts.FloatABI = getLastArgValue(Args, OPT_mfloat_abi);
Opts.LimitFloatPrecision = getLastArgValue(Args, OPT_mlimit_float_precision);
Opts.NoZeroInitializedInBSS = Args.hasArg(OPT_mno_zero_initialized_in_bss);
+ Opts.ObjCLegacyDispatch = Args.hasArg(OPT_fobjc_legacy_dispatch);
Opts.SoftFloat = Args.hasArg(OPT_msoft_float);
Opts.UnwindTables = Args.hasArg(OPT_munwind_tables);
Opts.RelocationModel = getLastArgValue(Args, OPT_mrelocation_model, "pic");
Opts.MainFileName = getLastArgValue(Args, OPT_main_file_name);
-
- // FIXME: Put elsewhere?
-#ifdef NDEBUG
- Opts.VerifyModule = 0;
-#else
- Opts.VerifyModule = 1;
-#endif
+ Opts.VerifyModule = !Args.hasArg(OPT_disable_llvm_verifier);
}
static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
@@ -808,6 +818,7 @@ static void ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
Opts.ShowOptionNames = Args.hasArg(OPT_fdiagnostics_show_option);
Opts.ShowSourceRanges = Args.hasArg(OPT_fdiagnostics_print_source_range_info);
Opts.VerifyDiagnostics = Args.hasArg(OPT_verify);
+ Opts.BinaryOutput = Args.hasArg(OPT_fdiagnostics_binary);
Opts.TabStop = getLastArgIntValue(Args, OPT_ftabstop,
DiagnosticOptions::DefaultTabStop, Diags);
if (Opts.TabStop == 0 || Opts.TabStop > DiagnosticOptions::MaxTabStop) {
@@ -852,6 +863,8 @@ ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Diagnostic &Diags) {
Opts.ProgramAction = frontend::EmitLLVM; break;
case OPT_emit_llvm_only:
Opts.ProgramAction = frontend::EmitLLVMOnly; break;
+ case OPT_emit_obj:
+ Opts.ProgramAction = frontend::EmitObj; break;
case OPT_fixit:
Opts.ProgramAction = frontend::FixIt; break;
case OPT_emit_pch:
@@ -920,6 +933,7 @@ ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Diagnostic &Diags) {
Opts.ShowTimers = Args.hasArg(OPT_ftime_report);
Opts.ShowVersion = Args.hasArg(OPT_version);
Opts.ViewClassInheritance = getLastArgValue(Args, OPT_cxx_inheritance_view);
+ Opts.ASTMergeFiles = getAllArgValues(Args, OPT_ast_merge);
FrontendOptions::InputKind DashX = FrontendOptions::IK_None;
if (const Arg *A = Args.getLastArg(OPT_x)) {
@@ -1146,7 +1160,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
if (Args.hasArg(OPT_fno_lax_vector_conversions))
- Opts.LaxVectorConversions = 0;
+ Opts.LaxVectorConversions = 0;
+ if (Args.hasArg(OPT_fno_threadsafe_statics))
+ Opts.ThreadsafeStatics = 0;
Opts.Exceptions = Args.hasArg(OPT_fexceptions);
Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
Opts.Blocks = Args.hasArg(OPT_fblocks);
@@ -1165,10 +1181,15 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.ObjCConstantStringClass = getLastArgValue(Args,
OPT_fconstant_string_class);
Opts.ObjCNonFragileABI = Args.hasArg(OPT_fobjc_nonfragile_abi);
+ Opts.ObjCNonFragileABI2 = Args.hasArg(OPT_fobjc_nonfragile_abi2);
+ if (Opts.ObjCNonFragileABI2)
+ Opts.ObjCNonFragileABI = true;
Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
+ Opts.SjLjExceptions = Args.hasArg(OPT_fsjlj_exceptions);
Opts.Static = Args.hasArg(OPT_static_define);
+ Opts.DumpVtableLayouts = Args.hasArg(OPT_fdump_vtable_layouts);
Opts.OptimizeSize = 0;
// FIXME: Eliminate this dependency.
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index 0baba3f..1c958a7 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -177,6 +177,9 @@ ASTConsumer *CodeGenAction::CreateASTConsumer(CompilerInstance &CI,
break;
case Backend_EmitNothing:
break;
+ case Backend_EmitObj:
+ OS.reset(CI.createDefaultOutputFile(true, InFile, "o"));
+ break;
}
if (BA != Backend_EmitNothing && !OS)
return 0;
@@ -196,6 +199,8 @@ EmitLLVMAction::EmitLLVMAction() : CodeGenAction(Backend_EmitLL) {}
EmitLLVMOnlyAction::EmitLLVMOnlyAction() : CodeGenAction(Backend_EmitNothing) {}
+EmitObjAction::EmitObjAction() : CodeGenAction(Backend_EmitObj) {}
+
//===----------------------------------------------------------------------===//
// Preprocessor Actions
//===----------------------------------------------------------------------===//
diff --git a/lib/Frontend/HTMLDiagnostics.cpp b/lib/Frontend/HTMLDiagnostics.cpp
index b163e26..f695254 100644
--- a/lib/Frontend/HTMLDiagnostics.cpp
+++ b/lib/Frontend/HTMLDiagnostics.cpp
@@ -12,7 +12,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Frontend/PathDiagnosticClients.h"
-#include "clang/Analysis/PathDiagnostic.h"
+#include "clang/Checker/BugReporter/PathDiagnostic.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/Basic/SourceManager.h"
diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp
index 6102760..2e0b4bd 100644
--- a/lib/Frontend/InitHeaderSearch.cpp
+++ b/lib/Frontend/InitHeaderSearch.cpp
@@ -483,10 +483,10 @@ void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(const llvm::Triple &tripl
AddPath("/usr/include/c++/4.1", System, true, false, false);
break;
case llvm::Triple::Linux:
- // Exherbo (2009-10-26)
- AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.2",
+ // Exherbo (2010-01-25)
+ AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
"x86_64-pc-linux-gnu", "32", "", triple);
- AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.2",
+ AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
"i686-pc-linux-gnu", "", "", triple);
// Debian sid
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.2",
@@ -522,6 +522,10 @@ void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(const llvm::Triple &tripl
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.2",
"i686-redhat-linux","", "", triple);
+ // Fedora 12 (February-2010+)
+ AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
+ "i686-redhat-linux","", "", triple);
+
// openSUSE 11.1 32 bit
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
"i586-suse-linux", "", "", triple);
diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
index 9aaf132..b7ab3d8 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -279,6 +279,8 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
if (LangOpts.Exceptions)
Builder.defineMacro("__EXCEPTIONS");
+ if (LangOpts.SjLjExceptions)
+ Builder.defineMacro("__USING_SJLJ_EXCEPTIONS__");
if (LangOpts.CPlusPlus) {
Builder.defineMacro("__DEPRECATED");
diff --git a/lib/Frontend/Makefile b/lib/Frontend/Makefile
index 8d70847..a630b01 100644
--- a/lib/Frontend/Makefile
+++ b/lib/Frontend/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../../../..
LIBRARYNAME := clangFrontend
BUILD_ARCHIVE = 1
-CXXFLAGS = -fno-rtti
CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index 2593551..a878df7 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -72,12 +72,14 @@ PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) {
PARSE_LANGOPT_IMPORTANT(ObjC1, diag::warn_pch_objective_c);
PARSE_LANGOPT_IMPORTANT(ObjC2, diag::warn_pch_objective_c2);
PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI, diag::warn_pch_nonfragile_abi);
+ PARSE_LANGOPT_IMPORTANT(ObjCNonFragileABI2, diag::warn_pch_nonfragile_abi2);
PARSE_LANGOPT_BENIGN(PascalStrings);
PARSE_LANGOPT_BENIGN(WritableStrings);
PARSE_LANGOPT_IMPORTANT(LaxVectorConversions,
diag::warn_pch_lax_vector_conversions);
PARSE_LANGOPT_IMPORTANT(AltiVec, diag::warn_pch_altivec);
PARSE_LANGOPT_IMPORTANT(Exceptions, diag::warn_pch_exceptions);
+ PARSE_LANGOPT_IMPORTANT(SjLjExceptions, diag::warn_pch_sjlj_exceptions);
PARSE_LANGOPT_IMPORTANT(NeXTRuntime, diag::warn_pch_objc_runtime);
PARSE_LANGOPT_IMPORTANT(Freestanding, diag::warn_pch_freestanding);
PARSE_LANGOPT_IMPORTANT(NoBuiltin, diag::warn_pch_builtins);
@@ -434,7 +436,9 @@ public:
continue;
}
- Prev->Next = new ObjCMethodList(Method, 0);
+ ObjCMethodList *Mem =
+ Reader.getSema()->BumpAlloc.Allocate<ObjCMethodList>();
+ Prev->Next = new (Mem) ObjCMethodList(Method, 0);
Prev = Prev->Next;
}
@@ -450,7 +454,9 @@ public:
continue;
}
- Prev->Next = new ObjCMethodList(Method, 0);
+ ObjCMethodList *Mem =
+ Reader.getSema()->BumpAlloc.Allocate<ObjCMethodList>();
+ Prev->Next = new (Mem) ObjCMethodList(Method, 0);
Prev = Prev->Next;
}
@@ -1326,6 +1332,14 @@ PCHReader::ReadPCHBlock() {
TentativeDefinitions.swap(Record);
break;
+ case pch::UNUSED_STATIC_FUNCS:
+ if (!UnusedStaticFuncs.empty()) {
+ Error("duplicate UNUSED_STATIC_FUNCS record in PCH file");
+ return Failure;
+ }
+ UnusedStaticFuncs.swap(Record);
+ break;
+
case pch::LOCALLY_SCOPED_EXTERNAL_DECLS:
if (!LocallyScopedExternalDecls.empty()) {
Error("duplicate LOCALLY_SCOPED_EXTERNAL_DECLS record in PCH file");
@@ -1400,9 +1414,9 @@ PCHReader::ReadPCHBlock() {
break;
case pch::VERSION_CONTROL_BRANCH_REVISION: {
- llvm::StringRef CurBranch = getClangFullRepositoryVersion();
+ const std::string &CurBranch = getClangFullRepositoryVersion();
llvm::StringRef PCHBranch(BlobStart, BlobLen);
- if (CurBranch != PCHBranch) {
+ if (llvm::StringRef(CurBranch) != PCHBranch) {
Diag(diag::warn_pch_different_branch) << PCHBranch << CurBranch;
return IgnorePCH;
}
@@ -1740,11 +1754,13 @@ bool PCHReader::ParseLanguageOptions(
PARSE_LANGOPT(ObjC1);
PARSE_LANGOPT(ObjC2);
PARSE_LANGOPT(ObjCNonFragileABI);
+ PARSE_LANGOPT(ObjCNonFragileABI2);
PARSE_LANGOPT(PascalStrings);
PARSE_LANGOPT(WritableStrings);
PARSE_LANGOPT(LaxVectorConversions);
PARSE_LANGOPT(AltiVec);
PARSE_LANGOPT(Exceptions);
+ PARSE_LANGOPT(SjLjExceptions);
PARSE_LANGOPT(NeXTRuntime);
PARSE_LANGOPT(Freestanding);
PARSE_LANGOPT(NoBuiltin);
@@ -1880,18 +1896,20 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
}
case pch::TYPE_VECTOR: {
- if (Record.size() != 2) {
+ if (Record.size() != 4) {
Error("incorrect encoding of vector type in PCH file");
return QualType();
}
QualType ElementType = GetType(Record[0]);
unsigned NumElements = Record[1];
- return Context->getVectorType(ElementType, NumElements);
+ bool AltiVec = Record[2];
+ bool Pixel = Record[3];
+ return Context->getVectorType(ElementType, NumElements, AltiVec, Pixel);
}
case pch::TYPE_EXT_VECTOR: {
- if (Record.size() != 2) {
+ if (Record.size() != 4) {
Error("incorrect encoding of extended vector type in PCH file");
return QualType();
}
@@ -2464,11 +2482,17 @@ void PCHReader::InitializeSema(Sema &S) {
PreloadedDecls.clear();
// If there were any tentative definitions, deserialize them and add
- // them to Sema's table of tentative definitions.
+ // them to Sema's list of tentative definitions.
for (unsigned I = 0, N = TentativeDefinitions.size(); I != N; ++I) {
VarDecl *Var = cast<VarDecl>(GetDecl(TentativeDefinitions[I]));
- SemaObj->TentativeDefinitions[Var->getDeclName()] = Var;
- SemaObj->TentativeDefinitionList.push_back(Var->getDeclName());
+ SemaObj->TentativeDefinitions.push_back(Var);
+ }
+
+ // If there were any unused static functions, deserialize them and add to
+ // Sema's list of unused static functions.
+ for (unsigned I = 0, N = UnusedStaticFuncs.size(); I != N; ++I) {
+ FunctionDecl *FD = cast<FunctionDecl>(GetDecl(UnusedStaticFuncs[I]));
+ SemaObj->UnusedStaticFuncs.push_back(FD);
}
// If there were any locally-scoped external declarations,
diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp
index 4dc1318..625997c 100644
--- a/lib/Frontend/PCHReaderDecl.cpp
+++ b/lib/Frontend/PCHReaderDecl.cpp
@@ -117,6 +117,7 @@ void PCHDeclReader::VisitTagDecl(TagDecl *TD) {
cast_or_null<TagDecl>(Reader.GetDecl(Record[Idx++])));
TD->setTagKind((TagDecl::TagKind)Record[Idx++]);
TD->setDefinition(Record[Idx++]);
+ TD->setEmbeddedInDeclarator(Record[Idx++]);
TD->setTypedefForAnonDecl(
cast_or_null<TypedefDecl>(Reader.GetDecl(Record[Idx++])));
TD->setRBraceLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
@@ -179,7 +180,7 @@ void PCHDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
Params.reserve(NumParams);
for (unsigned I = 0; I != NumParams; ++I)
Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
- FD->setParams(*Reader.getContext(), Params.data(), NumParams);
+ FD->setParams(Params.data(), NumParams);
}
void PCHDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
@@ -387,7 +388,7 @@ void PCHDeclReader::VisitVarDecl(VarDecl *VD) {
VD->setPreviousDeclaration(
cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
if (Record[Idx++])
- VD->setInit(*Reader.getContext(), Reader.ReadDeclExpr());
+ VD->setInit(Reader.ReadDeclExpr());
}
void PCHDeclReader::VisitImplicitParamDecl(ImplicitParamDecl *PD) {
@@ -412,7 +413,7 @@ void PCHDeclReader::VisitBlockDecl(BlockDecl *BD) {
Params.reserve(NumParams);
for (unsigned I = 0; I != NumParams; ++I)
Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
- BD->setParams(*Reader.getContext(), Params.data(), NumParams);
+ BD->setParams(Params.data(), NumParams);
}
std::pair<uint64_t, uint64_t>
@@ -445,7 +446,7 @@ Attr *PCHReader::ReadAttributes() {
#define STRING_ATTR(Name) \
case Attr::Name: \
- New = ::new (*Context) Name##Attr(ReadString(Record, Idx)); \
+ New = ::new (*Context) Name##Attr(*Context, ReadString(Record, Idx)); \
break
#define UNSIGNED_ATTR(Name) \
@@ -496,7 +497,7 @@ Attr *PCHReader::ReadAttributes() {
std::string Type = ReadString(Record, Idx);
unsigned FormatIdx = Record[Idx++];
unsigned FirstArg = Record[Idx++];
- New = ::new (*Context) FormatAttr(Type, FormatIdx, FirstArg);
+ New = ::new (*Context) FormatAttr(*Context, Type, FormatIdx, FirstArg);
break;
}
@@ -531,7 +532,7 @@ Attr *PCHReader::ReadAttributes() {
llvm::SmallVector<unsigned, 16> ArgNums;
ArgNums.insert(ArgNums.end(), &Record[Idx], &Record[Idx] + Size);
Idx += Size;
- New = ::new (*Context) NonNullAttr(ArgNums.data(), Size);
+ New = ::new (*Context) NonNullAttr(*Context, ArgNums.data(), Size);
break;
}
diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp
index 21c9cbf..d123694 100644
--- a/lib/Frontend/PCHReaderStmt.cpp
+++ b/lib/Frontend/PCHReaderStmt.cpp
@@ -123,6 +123,8 @@ namespace {
unsigned VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E);
unsigned VisitCXXConstCastExpr(CXXConstCastExpr *E);
unsigned VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E);
+ unsigned VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E);
+ unsigned VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E);
};
}
@@ -317,22 +319,24 @@ unsigned PCHStmtReader::VisitAsmStmt(AsmStmt *S) {
S->setAsmString(cast_or_null<StringLiteral>(StmtStack[StackIdx++]));
// Outputs and inputs
- llvm::SmallVector<std::string, 16> Names;
+ llvm::SmallVector<IdentifierInfo *, 16> Names;
llvm::SmallVector<StringLiteral*, 16> Constraints;
llvm::SmallVector<Stmt*, 16> Exprs;
for (unsigned I = 0, N = NumOutputs + NumInputs; I != N; ++I) {
- Names.push_back(Reader.ReadString(Record, Idx));
+ Names.push_back(Reader.GetIdentifierInfo(Record, Idx));
Constraints.push_back(cast_or_null<StringLiteral>(StmtStack[StackIdx++]));
Exprs.push_back(StmtStack[StackIdx++]);
}
- S->setOutputsAndInputs(NumOutputs, NumInputs,
- Names.data(), Constraints.data(), Exprs.data());
// Constraints
llvm::SmallVector<StringLiteral*, 16> Clobbers;
for (unsigned I = 0; I != NumClobbers; ++I)
Clobbers.push_back(cast_or_null<StringLiteral>(StmtStack[StackIdx++]));
- S->setClobbers(Clobbers.data(), NumClobbers);
+
+ S->setOutputsAndInputsAndClobbers(*Reader.getContext(),
+ Names.data(), Constraints.data(),
+ Exprs.data(), NumOutputs, NumInputs,
+ Clobbers.data(), NumClobbers);
assert(StackIdx == StmtStack.size() && "Error deserializing AsmStmt");
return NumOutputs*2 + NumInputs*2 + NumClobbers + 1;
@@ -904,6 +908,19 @@ unsigned PCHStmtReader::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
return num;
}
+unsigned PCHStmtReader::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
+ VisitExpr(E);
+ E->setValue(Record[Idx++]);
+ E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ return 0;
+}
+
+unsigned PCHStmtReader::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
+ VisitExpr(E);
+ E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ return 0;
+}
+
// Within the bitstream, expressions are stored in Reverse Polish
// Notation, with each of the subexpressions preceding the
// expression they are stored in. To evaluate expressions, we
@@ -1233,7 +1250,13 @@ Stmt *PCHReader::ReadStmt(llvm::BitstreamCursor &Cursor) {
S = new (Context) CXXFunctionalCastExpr(Empty);
break;
+ case pch::EXPR_CXX_BOOL_LITERAL:
+ S = new (Context) CXXBoolLiteralExpr(Empty);
+ break;
+ case pch::EXPR_CXX_NULL_PTR_LITERAL:
+ S = new (Context) CXXNullPtrLiteralExpr(Empty);
+ break;
}
// We hit a STMT_STOP, so we're done with this expression.
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index 9909c95..4c99dbe 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -128,6 +128,8 @@ void PCHTypeWriter::VisitVariableArrayType(const VariableArrayType *T) {
void PCHTypeWriter::VisitVectorType(const VectorType *T) {
Writer.AddTypeRef(T->getElementType(), Record);
Record.push_back(T->getNumElements());
+ Record.push_back(T->isAltiVec());
+ Record.push_back(T->isPixel());
Code = pch::TYPE_VECTOR;
}
@@ -511,6 +513,15 @@ static void AddStmtsExprs(llvm::BitstreamWriter &Stream,
RECORD(STMT_OBJC_AT_TRY);
RECORD(STMT_OBJC_AT_SYNCHRONIZED);
RECORD(STMT_OBJC_AT_THROW);
+ RECORD(EXPR_CXX_OPERATOR_CALL);
+ RECORD(EXPR_CXX_CONSTRUCT);
+ RECORD(EXPR_CXX_STATIC_CAST);
+ RECORD(EXPR_CXX_DYNAMIC_CAST);
+ RECORD(EXPR_CXX_REINTERPRET_CAST);
+ RECORD(EXPR_CXX_CONST_CAST);
+ RECORD(EXPR_CXX_FUNCTIONAL_CAST);
+ RECORD(EXPR_CXX_BOOL_LITERAL);
+ RECORD(EXPR_CXX_NULL_PTR_LITERAL);
#undef RECORD
}
@@ -534,6 +545,7 @@ void PCHWriter::WriteBlockInfoBlock() {
RECORD(SPECIAL_TYPES);
RECORD(STATISTICS);
RECORD(TENTATIVE_DEFINITIONS);
+ RECORD(UNUSED_STATIC_FUNCS);
RECORD(LOCALLY_SCOPED_EXTERNAL_DECLS);
RECORD(SELECTOR_OFFSETS);
RECORD(METHOD_POOL);
@@ -737,13 +749,17 @@ void PCHWriter::WriteLanguageOptions(const LangOptions &LangOpts) {
Record.push_back(LangOpts.ObjC1); // Objective-C 1 support enabled.
Record.push_back(LangOpts.ObjC2); // Objective-C 2 support enabled.
- Record.push_back(LangOpts.ObjCNonFragileABI); // Objective-C modern abi enabled
+ Record.push_back(LangOpts.ObjCNonFragileABI); // Objective-C
+ // modern abi enabled.
+ Record.push_back(LangOpts.ObjCNonFragileABI2); // Objective-C enhanced
+ // modern abi enabled.
Record.push_back(LangOpts.PascalStrings); // Allow Pascal strings
Record.push_back(LangOpts.WritableStrings); // Allow writable strings
Record.push_back(LangOpts.LaxVectorConversions);
Record.push_back(LangOpts.AltiVec);
Record.push_back(LangOpts.Exceptions); // Support exception handling.
+ Record.push_back(LangOpts.SjLjExceptions);
Record.push_back(LangOpts.NeXTRuntime); // Use NeXT runtime.
Record.push_back(LangOpts.Freestanding); // Freestanding implementation
@@ -1960,15 +1976,18 @@ void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,
}
// Build a record containing all of the tentative definitions in this file, in
- // TentativeDefinitionList order. Generally, this record will be empty for
+ // TentativeDefinitions order. Generally, this record will be empty for
// headers.
RecordData TentativeDefinitions;
- for (unsigned i = 0, e = SemaRef.TentativeDefinitionList.size(); i != e; ++i){
- VarDecl *VD =
- SemaRef.TentativeDefinitions.lookup(SemaRef.TentativeDefinitionList[i]);
- if (VD) AddDeclRef(VD, TentativeDefinitions);
+ for (unsigned i = 0, e = SemaRef.TentativeDefinitions.size(); i != e; ++i) {
+ AddDeclRef(SemaRef.TentativeDefinitions[i], TentativeDefinitions);
}
+ // Build a record containing all of the static unused functions in this file.
+ RecordData UnusedStaticFuncs;
+ for (unsigned i=0, e = SemaRef.UnusedStaticFuncs.size(); i !=e; ++i)
+ AddDeclRef(SemaRef.UnusedStaticFuncs[i], UnusedStaticFuncs);
+
// Build a record containing all of the locally-scoped external
// declarations in this header file. Generally, this record will be
// empty.
@@ -2070,6 +2089,10 @@ void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,
if (!TentativeDefinitions.empty())
Stream.EmitRecord(pch::TENTATIVE_DEFINITIONS, TentativeDefinitions);
+ // Write the record containing unused static functions.
+ if (!UnusedStaticFuncs.empty())
+ Stream.EmitRecord(pch::UNUSED_STATIC_FUNCS, UnusedStaticFuncs);
+
// Write the record containing locally-scoped external definitions.
if (!LocallyScopedExternalDecls.empty())
Stream.EmitRecord(pch::LOCALLY_SCOPED_EXTERNAL_DECLS,
diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp
index 020f69b..d105382 100644
--- a/lib/Frontend/PCHWriterDecl.cpp
+++ b/lib/Frontend/PCHWriterDecl.cpp
@@ -115,6 +115,7 @@ void PCHDeclWriter::VisitTagDecl(TagDecl *D) {
Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
Record.push_back((unsigned)D->getTagKind()); // FIXME: stable encoding
Record.push_back(D->isDefinition());
+ Record.push_back(D->isEmbeddedInDeclarator());
Writer.AddDeclRef(D->getTypedefForAnonDecl(), Record);
Writer.AddSourceLocation(D->getRBraceLoc(), Record);
Writer.AddSourceLocation(D->getTagKeywordLoc(), Record);
diff --git a/lib/Frontend/PCHWriterStmt.cpp b/lib/Frontend/PCHWriterStmt.cpp
index fdfdfef..a8cc9d6 100644
--- a/lib/Frontend/PCHWriterStmt.cpp
+++ b/lib/Frontend/PCHWriterStmt.cpp
@@ -118,6 +118,8 @@ namespace {
void VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr *E);
void VisitCXXConstCastExpr(CXXConstCastExpr *E);
void VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E);
+ void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E);
+ void VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E);
};
}
@@ -287,15 +289,15 @@ void PCHStmtWriter::VisitAsmStmt(AsmStmt *S) {
Writer.WriteSubStmt(S->getAsmString());
// Outputs
- for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
- Writer.AddString(S->getOutputName(I), Record);
+ for (unsigned I = 0, N = S->getNumOutputs(); I != N; ++I) {
+ Writer.AddIdentifierRef(S->getOutputIdentifier(I), Record);
Writer.WriteSubStmt(S->getOutputConstraintLiteral(I));
Writer.WriteSubStmt(S->getOutputExpr(I));
}
// Inputs
for (unsigned I = 0, N = S->getNumInputs(); I != N; ++I) {
- Writer.AddString(S->getInputName(I), Record);
+ Writer.AddIdentifierRef(S->getInputIdentifier(I), Record);
Writer.WriteSubStmt(S->getInputConstraintLiteral(I));
Writer.WriteSubStmt(S->getInputExpr(I));
}
@@ -834,6 +836,19 @@ void PCHStmtWriter::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E) {
Code = pch::EXPR_CXX_FUNCTIONAL_CAST;
}
+void PCHStmtWriter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
+ VisitExpr(E);
+ Record.push_back(E->getValue());
+ Writer.AddSourceLocation(E->getLocation(), Record);
+ Code = pch::EXPR_CXX_BOOL_LITERAL;
+}
+
+void PCHStmtWriter::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
+ VisitExpr(E);
+ Writer.AddSourceLocation(E->getLocation(), Record);
+ Code = pch::EXPR_CXX_NULL_PTR_LITERAL;
+}
+
//===----------------------------------------------------------------------===//
// PCHWriter Implementation
//===----------------------------------------------------------------------===//
diff --git a/lib/Frontend/PlistDiagnostics.cpp b/lib/Frontend/PlistDiagnostics.cpp
index 98be869..5706a07 100644
--- a/lib/Frontend/PlistDiagnostics.cpp
+++ b/lib/Frontend/PlistDiagnostics.cpp
@@ -12,7 +12,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Frontend/PathDiagnosticClients.h"
-#include "clang/Analysis/PathDiagnostic.h"
+#include "clang/Checker/BugReporter/PathDiagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/FileManager.h"
#include "clang/Lex/Preprocessor.h"
diff --git a/lib/Frontend/PrintParserCallbacks.cpp b/lib/Frontend/PrintParserCallbacks.cpp
index a91dd8d..8d64a64 100644
--- a/lib/Frontend/PrintParserCallbacks.cpp
+++ b/lib/Frontend/PrintParserCallbacks.cpp
@@ -391,7 +391,7 @@ namespace {
bool IsVolatile,
unsigned NumOutputs,
unsigned NumInputs,
- std::string *Names,
+ IdentifierInfo **Names,
MultiExprArg Constraints,
MultiExprArg Exprs,
ExprArg AsmString,
@@ -684,7 +684,8 @@ namespace {
virtual DeclPtrTy ActOnStartNamespaceDef(Scope *S, SourceLocation IdentLoc,
IdentifierInfo *Ident,
- SourceLocation LBrace) {
+ SourceLocation LBrace,
+ AttributeList *AttrList) {
Out << __FUNCTION__ << "\n";
return DeclPtrTy();
}
diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp
index 35d8dde..9dade66 100644
--- a/lib/Frontend/RewriteObjC.cpp
+++ b/lib/Frontend/RewriteObjC.cpp
@@ -124,8 +124,10 @@ namespace {
llvm::DenseMap<BlockDeclRefExpr *, CallExpr *> BlockCallExprs;
// Block related declarations.
- llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDecls;
- llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDecls;
+ llvm::SmallVector<ValueDecl *, 8> BlockByCopyDecls;
+ llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet;
+ llvm::SmallVector<ValueDecl *, 8> BlockByRefDecls;
+ llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet;
llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
@@ -212,11 +214,10 @@ namespace {
<< Old->getSourceRange();
}
- void InsertText(SourceLocation Loc, const char *StrData, unsigned StrLen,
+ void InsertText(SourceLocation Loc, llvm::StringRef Str,
bool InsertAfter = true) {
// If insertion succeeded or warning disabled return with no warning.
- if (!Rewrite.InsertText(Loc, llvm::StringRef(StrData, StrLen),
- InsertAfter) ||
+ if (!Rewrite.InsertText(Loc, Str, InsertAfter) ||
SilenceRewriteMacroWarning)
return;
@@ -232,10 +233,9 @@ namespace {
}
void ReplaceText(SourceLocation Start, unsigned OrigLength,
- const char *NewStr, unsigned NewLength) {
+ llvm::StringRef Str) {
// If removal succeeded or warning disabled return with no warning.
- if (!Rewrite.ReplaceText(Start, OrigLength,
- llvm::StringRef(NewStr, NewLength)) ||
+ if (!Rewrite.ReplaceText(Start, OrigLength, Str) ||
SilenceRewriteMacroWarning)
return;
@@ -263,6 +263,7 @@ namespace {
void RewriteFunctionDecl(FunctionDecl *FD);
void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD);
void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl);
+ void RewriteTypeOfDecl(VarDecl *VD);
void RewriteObjCQualifiedInterfaceTypes(Expr *E);
bool needToScanForQualifiers(QualType T);
ObjCInterfaceDecl *isSuperReceiver(Expr *recExpr);
@@ -278,7 +279,9 @@ namespace {
ParentMap *PropParentMap; // created lazily.
Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp);
- Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV, SourceLocation OrigStart);
+ Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV, SourceLocation OrigStart,
+ bool &replaced);
+ Stmt *RewriteObjCNestedIvarRefExpr(Stmt *S, bool &replaced);
Stmt *RewritePropertyGetter(ObjCPropertyRefExpr *PropRefExpr);
Stmt *RewritePropertySetter(BinaryOperator *BinOp, Expr *newStmt,
SourceRange SrcRange);
@@ -632,6 +635,9 @@ void RewriteObjC::Initialize(ASTContext &context) {
//===----------------------------------------------------------------------===//
void RewriteObjC::HandleTopLevelSingleDecl(Decl *D) {
+ if (Diags.hasErrorOccurred())
+ return;
+
// Two cases: either the decl could be in the main file, or it could be in a
// #included file. If the former, rewrite it now. If the later, check to see
// if we rewrote the #include/#import.
@@ -681,7 +687,6 @@ void RewriteObjC::RewriteInclude() {
const char *MainBufStart = MainBuf.first;
const char *MainBufEnd = MainBuf.second;
size_t ImportLen = strlen("import");
- size_t IncludeLen = strlen("include");
// Loop over the whole file, looking for includes.
for (const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
@@ -695,7 +700,7 @@ void RewriteObjC::RewriteInclude() {
// replace import with include
SourceLocation ImportLoc =
LocStart.getFileLocWithOffset(BufPtr-MainBufStart);
- ReplaceText(ImportLoc, ImportLen, "include", IncludeLen);
+ ReplaceText(ImportLoc, ImportLen, "include");
BufPtr += ImportLen;
}
}
@@ -728,7 +733,7 @@ void RewriteObjC::RewriteTabs() {
TabLoc = TabLoc.getFileLocWithOffset(BufPtr-MainBufStart);
// Rewrite the single tab character into a sequence of spaces.
- ReplaceText(TabLoc, 1, " ", Spaces);
+ ReplaceText(TabLoc, 1, llvm::StringRef(" ", Spaces));
}
}
@@ -746,7 +751,7 @@ void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
ObjCImplementationDecl *IMD,
ObjCCategoryImplDecl *CID) {
SourceLocation startLoc = PID->getLocStart();
- InsertText(startLoc, "// ", 3);
+ InsertText(startLoc, "// ");
const char *startBuf = SM->getCharacterData(startLoc);
assert((*startBuf == '@') && "bogus @synthesize location");
const char *semiBuf = strchr(startBuf, ';');
@@ -774,7 +779,7 @@ void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
// See objc-act.c:objc_synthesize_new_getter() for details.
Getr += "return " + getIvarAccessString(ClassDecl, OID);
Getr += "; }";
- InsertText(onePastSemiLoc, Getr.c_str(), Getr.size());
+ InsertText(onePastSemiLoc, Getr);
if (PD->isReadOnly())
return;
@@ -789,7 +794,7 @@ void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
Setr += getIvarAccessString(ClassDecl, OID) + " = ";
Setr += PD->getNameAsCString();
Setr += "; }";
- InsertText(onePastSemiLoc, Setr.c_str(), Setr.size());
+ InsertText(onePastSemiLoc, Setr);
}
void RewriteObjC::RewriteForwardClassDecl(ObjCClassDecl *ClassDecl) {
@@ -828,8 +833,7 @@ void RewriteObjC::RewriteForwardClassDecl(ObjCClassDecl *ClassDecl) {
}
// Replace the @class with typedefs corresponding to the classes.
- ReplaceText(startLoc, semiPtr-startBuf+1,
- typedefString.c_str(), typedefString.size());
+ ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);
}
void RewriteObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) {
@@ -842,17 +846,17 @@ void RewriteObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) {
if (SM->getInstantiationLineNumber(LocEnd) >
SM->getInstantiationLineNumber(LocStart)) {
- InsertText(LocStart, "#if 0\n", 6);
- ReplaceText(LocEnd, 1, ";\n#endif\n", 9);
+ InsertText(LocStart, "#if 0\n");
+ ReplaceText(LocEnd, 1, ";\n#endif\n");
} else {
- InsertText(LocStart, "// ", 3);
+ InsertText(LocStart, "// ");
}
}
void RewriteObjC::RewriteProperty(ObjCPropertyDecl *prop) {
SourceLocation Loc = prop->getAtLoc();
- ReplaceText(Loc, 0, "// ", 3);
+ ReplaceText(Loc, 0, "// ");
// FIXME: handle properties that are declared across multiple lines.
}
@@ -860,8 +864,12 @@ void RewriteObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
SourceLocation LocStart = CatDecl->getLocStart();
// FIXME: handle category headers that are declared across multiple lines.
- ReplaceText(LocStart, 0, "// ", 3);
+ ReplaceText(LocStart, 0, "// ");
+ for (ObjCCategoryDecl::prop_iterator I = CatDecl->prop_begin(),
+ E = CatDecl->prop_end(); I != E; ++I)
+ RewriteProperty(*I);
+
for (ObjCCategoryDecl::instmeth_iterator
I = CatDecl->instmeth_begin(), E = CatDecl->instmeth_end();
I != E; ++I)
@@ -872,7 +880,7 @@ void RewriteObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
RewriteMethodDeclaration(*I);
// Lastly, comment out the @end.
- ReplaceText(CatDecl->getAtEndRange().getBegin(), 0, "// ", 3);
+ ReplaceText(CatDecl->getAtEndRange().getBegin(), 0, "// ");
}
void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
@@ -881,7 +889,7 @@ void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
SourceLocation LocStart = PDecl->getLocStart();
// FIXME: handle protocol headers that are declared across multiple lines.
- ReplaceText(LocStart, 0, "// ", 3);
+ ReplaceText(LocStart, 0, "// ");
for (ObjCProtocolDecl::instmeth_iterator
I = PDecl->instmeth_begin(), E = PDecl->instmeth_end();
@@ -894,24 +902,20 @@ void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
// Lastly, comment out the @end.
SourceLocation LocEnd = PDecl->getAtEndRange().getBegin();
- ReplaceText(LocEnd, 0, "// ", 3);
+ ReplaceText(LocEnd, 0, "// ");
// Must comment out @optional/@required
const char *startBuf = SM->getCharacterData(LocStart);
const char *endBuf = SM->getCharacterData(LocEnd);
for (const char *p = startBuf; p < endBuf; p++) {
if (*p == '@' && !strncmp(p+1, "optional", strlen("optional"))) {
- std::string CommentedOptional = "/* @optional */";
SourceLocation OptionalLoc = LocStart.getFileLocWithOffset(p-startBuf);
- ReplaceText(OptionalLoc, strlen("@optional"),
- CommentedOptional.c_str(), CommentedOptional.size());
+ ReplaceText(OptionalLoc, strlen("@optional"), "/* @optional */");
}
else if (*p == '@' && !strncmp(p+1, "required", strlen("required"))) {
- std::string CommentedRequired = "/* @required */";
SourceLocation OptionalLoc = LocStart.getFileLocWithOffset(p-startBuf);
- ReplaceText(OptionalLoc, strlen("@required"),
- CommentedRequired.c_str(), CommentedRequired.size());
+ ReplaceText(OptionalLoc, strlen("@required"), "/* @required */");
}
}
@@ -922,7 +926,7 @@ void RewriteObjC::RewriteForwardProtocolDecl(ObjCForwardProtocolDecl *PDecl) {
if (LocStart.isInvalid())
assert(false && "Invalid SourceLocation");
// FIXME: handle forward protocol that are declared across multiple lines.
- ReplaceText(LocStart, 0, "// ", 3);
+ ReplaceText(LocStart, 0, "// ");
}
void RewriteObjC::RewriteObjCMethodDecl(ObjCMethodDecl *OMD,
@@ -1050,10 +1054,7 @@ void RewriteObjC::RewriteImplementationDecl(Decl *OID) {
ObjCImplementationDecl *IMD = dyn_cast<ObjCImplementationDecl>(OID);
ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(OID);
- if (IMD)
- InsertText(IMD->getLocStart(), "// ", 3);
- else
- InsertText(CID->getLocStart(), "// ", 3);
+ InsertText(IMD ? IMD->getLocStart() : CID->getLocStart(), "// ");
for (ObjCCategoryImplDecl::instmeth_iterator
I = IMD ? IMD->instmeth_begin() : CID->instmeth_begin(),
@@ -1067,8 +1068,7 @@ void RewriteObjC::RewriteImplementationDecl(Decl *OID) {
const char *startBuf = SM->getCharacterData(LocStart);
const char *endBuf = SM->getCharacterData(LocEnd);
- ReplaceText(LocStart, endBuf-startBuf,
- ResultStr.c_str(), ResultStr.size());
+ ReplaceText(LocStart, endBuf-startBuf, ResultStr);
}
for (ObjCCategoryImplDecl::classmeth_iterator
@@ -1083,8 +1083,7 @@ void RewriteObjC::RewriteImplementationDecl(Decl *OID) {
const char *startBuf = SM->getCharacterData(LocStart);
const char *endBuf = SM->getCharacterData(LocEnd);
- ReplaceText(LocStart, endBuf-startBuf,
- ResultStr.c_str(), ResultStr.size());
+ ReplaceText(LocStart, endBuf-startBuf, ResultStr);
}
for (ObjCCategoryImplDecl::propimpl_iterator
I = IMD ? IMD->propimpl_begin() : CID->propimpl_begin(),
@@ -1093,10 +1092,7 @@ void RewriteObjC::RewriteImplementationDecl(Decl *OID) {
RewritePropertyImplDecl(*I, IMD, CID);
}
- if (IMD)
- InsertText(IMD->getLocEnd(), "// ", 3);
- else
- InsertText(CID->getLocEnd(), "// ", 3);
+ InsertText(IMD ? IMD->getLocEnd() : CID->getLocEnd(), "// ");
}
void RewriteObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
@@ -1130,7 +1126,7 @@ void RewriteObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
RewriteMethodDeclaration(*I);
// Lastly, comment out the @end.
- ReplaceText(ClassDecl->getAtEndRange().getBegin(), 0, "// ", 3);
+ ReplaceText(ClassDecl->getAtEndRange().getBegin(), 0, "// ");
}
Stmt *RewriteObjC::RewritePropertySetter(BinaryOperator *BinOp, Expr *newStmt,
@@ -1149,7 +1145,7 @@ Stmt *RewriteObjC::RewritePropertySetter(BinaryOperator *BinOp, Expr *newStmt,
// This allows us to handle chain/nested property getters.
Receiver = PropGetters[PRE];
}
- MsgExpr = new (Context) ObjCMessageExpr(dyn_cast<Expr>(Receiver),
+ MsgExpr = new (Context) ObjCMessageExpr(*Context, dyn_cast<Expr>(Receiver),
PDecl->getSetterName(), PDecl->getType(),
PDecl->getSetterMethodDecl(),
SourceLocation(), SourceLocation(),
@@ -1178,7 +1174,7 @@ Stmt *RewriteObjC::RewritePropertyGetter(ObjCPropertyRefExpr *PropRefExpr) {
// This allows us to handle chain/nested property getters.
Receiver = PropGetters[PRE];
}
- MsgExpr = new (Context) ObjCMessageExpr(dyn_cast<Expr>(Receiver),
+ MsgExpr = new (Context) ObjCMessageExpr(*Context, dyn_cast<Expr>(Receiver),
PDecl->getGetterName(), PDecl->getType(),
PDecl->getGetterMethodDecl(),
SourceLocation(), SourceLocation(),
@@ -1209,14 +1205,15 @@ Stmt *RewriteObjC::RewritePropertyGetter(ObjCPropertyRefExpr *PropRefExpr) {
}
Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV,
- SourceLocation OrigStart) {
+ SourceLocation OrigStart,
+ bool &replaced) {
ObjCIvarDecl *D = IV->getDecl();
const Expr *BaseExpr = IV->getBase();
if (CurMethodDef) {
- if (BaseExpr->getType()->isObjCObjectPointerType() &&
- isa<DeclRefExpr>(BaseExpr)) {
+ if (BaseExpr->getType()->isObjCObjectPointerType()) {
ObjCInterfaceType *iFaceDecl =
dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType());
+ assert(iFaceDecl && "RewriteObjCIvarRefExpr - iFaceDecl is null");
// lookup which class implements the instance variable.
ObjCInterfaceDecl *clsDeclared = 0;
iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(),
@@ -1226,7 +1223,7 @@ Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV,
// Synthesize an explicit cast to gain access to the ivar.
std::string RecName = clsDeclared->getIdentifier()->getName();
RecName += "_IMPL";
- IdentifierInfo *II = &Context->Idents.get(RecName.c_str());
+ IdentifierInfo *II = &Context->Idents.get(RecName);
RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
SourceLocation(), II);
assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
@@ -1238,17 +1235,16 @@ Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV,
ParenExpr *PE = new (Context) ParenExpr(IV->getBase()->getLocStart(),
IV->getBase()->getLocEnd(),
castExpr);
+ replaced = true;
if (IV->isFreeIvar() &&
CurMethodDef->getClassInterface() == iFaceDecl->getDecl()) {
MemberExpr *ME = new (Context) MemberExpr(PE, true, D,
IV->getLocation(),
D->getType());
- ReplaceStmt(IV, ME);
// delete IV; leak for now, see RewritePropertySetter() usage for more info.
return ME;
}
-
- ReplaceStmt(IV->getBase(), PE);
+ // Get the new text
// Cannot delete IV->getBase(), since PE points to it.
// Replace the old base with the cast. This is important when doing
// embedded rewrites. For example, [newInv->_container addObject:0].
@@ -1272,7 +1268,7 @@ Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV,
// Synthesize an explicit cast to gain access to the ivar.
std::string RecName = clsDeclared->getIdentifier()->getName();
RecName += "_IMPL";
- IdentifierInfo *II = &Context->Idents.get(RecName.c_str());
+ IdentifierInfo *II = &Context->Idents.get(RecName);
RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
SourceLocation(), II);
assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
@@ -1283,7 +1279,7 @@ Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV,
// Don't forget the parens to enforce the proper binding.
ParenExpr *PE = new (Context) ParenExpr(IV->getBase()->getLocStart(),
IV->getBase()->getLocEnd(), castExpr);
- ReplaceStmt(IV->getBase(), PE);
+ replaced = true;
// Cannot delete IV->getBase(), since PE points to it.
// Replace the old base with the cast. This is important when doing
// embedded rewrites. For example, [newInv->_container addObject:0].
@@ -1294,6 +1290,28 @@ Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV,
return IV;
}
+Stmt *RewriteObjC::RewriteObjCNestedIvarRefExpr(Stmt *S, bool &replaced) {
+ for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
+ CI != E; ++CI) {
+ if (*CI) {
+ Stmt *newStmt = RewriteObjCNestedIvarRefExpr(*CI, replaced);
+ if (newStmt)
+ *CI = newStmt;
+ }
+ }
+ if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
+ SourceRange OrigStmtRange = S->getSourceRange();
+ Stmt *newStmt = RewriteObjCIvarRefExpr(IvarRefExpr, OrigStmtRange.getBegin(),
+ replaced);
+ return newStmt;
+ }
+ if (ObjCMessageExpr *MsgRefExpr = dyn_cast<ObjCMessageExpr>(S)) {
+ Stmt *newStmt = SynthMessageExpr(MsgRefExpr);
+ return newStmt;
+ }
+ return S;
+}
+
/// SynthCountByEnumWithState - To print:
/// ((unsigned int (*)
/// (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int))
@@ -1326,7 +1344,7 @@ Stmt *RewriteObjC::RewriteBreakStmt(BreakStmt *S) {
SourceLocation startLoc = S->getLocStart();
buf = "goto __break_label_";
buf += utostr(ObjCBcLabelNo.back());
- ReplaceText(startLoc, strlen("break"), buf.c_str(), buf.size());
+ ReplaceText(startLoc, strlen("break"), buf);
return 0;
}
@@ -1343,7 +1361,7 @@ Stmt *RewriteObjC::RewriteContinueStmt(ContinueStmt *S) {
SourceLocation startLoc = S->getLocStart();
buf = "goto __continue_label_";
buf += utostr(ObjCBcLabelNo.back());
- ReplaceText(startLoc, strlen("continue"), buf.c_str(), buf.size());
+ ReplaceText(startLoc, strlen("continue"), buf);
return 0;
}
@@ -1442,8 +1460,7 @@ Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
startCollectionBuf += 3;
// Replace: "for (type element in" with string constructed thus far.
- ReplaceText(startLoc, startCollectionBuf - startBuf,
- buf.c_str(), buf.size());
+ ReplaceText(startLoc, startCollectionBuf - startBuf, buf);
// Replace ')' in for '(' type elem in collection ')' with ';'
SourceLocation rightParenLoc = S->getRParenLoc();
const char *rparenBuf = SM->getCharacterData(rightParenLoc);
@@ -1484,7 +1501,7 @@ Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
buf += elementTypeAsString;
buf += ")enumState.itemsPtr[counter++];";
// Replace ')' in for '(' type elem in collection ')' with all of these.
- ReplaceText(lparenLoc, 1, buf.c_str(), buf.size());
+ ReplaceText(lparenLoc, 1, buf);
/// __continue_label: ;
/// } while (counter < limit);
@@ -1525,7 +1542,7 @@ Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
// FIXME: If this should support Obj-C++, support CXXTryStmt
if (isa<CompoundStmt>(S->getBody())) {
SourceLocation endBodyLoc = OrigEnd.getFileLocWithOffset(1);
- InsertText(endBodyLoc, buf.c_str(), buf.size());
+ InsertText(endBodyLoc, buf);
} else {
/* Need to treat single statements specially. For example:
*
@@ -1538,7 +1555,7 @@ Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
const char *semiBuf = strchr(stmtBuf, ';');
assert(semiBuf && "Can't find ';'");
SourceLocation endBodyLoc = OrigEnd.getFileLocWithOffset(semiBuf-stmtBuf+1);
- InsertText(endBodyLoc, buf.c_str(), buf.size());
+ InsertText(endBodyLoc, buf);
}
Stmts.pop_back();
ObjCBcLabelNo.pop_back();
@@ -1562,7 +1579,7 @@ Stmt *RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
buf = "objc_sync_enter((id)";
const char *lparenBuf = startBuf;
while (*lparenBuf != '(') lparenBuf++;
- ReplaceText(startLoc, lparenBuf-startBuf+1, buf.c_str(), buf.size());
+ ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
// We can't use S->getSynchExpr()->getLocEnd() to find the end location, since
// the sync expression is typically a message expression that's already
// been rewritten! (which implies the SourceLocation's are invalid).
@@ -1578,7 +1595,7 @@ Stmt *RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
buf += "id volatile _rethrow = 0;\n";
buf += "objc_exception_try_enter(&_stack);\n";
buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
- ReplaceText(rparenLoc, 1, buf.c_str(), buf.size());
+ ReplaceText(rparenLoc, 1, buf);
startLoc = S->getSynchBody()->getLocEnd();
startBuf = SM->getCharacterData(startLoc);
@@ -1607,7 +1624,7 @@ Stmt *RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
buf += "}\n";
buf += "}";
- ReplaceText(lastCurlyLoc, 1, buf.c_str(), buf.size());
+ ReplaceText(lastCurlyLoc, 1, buf);
bool hasReturns = false;
HasReturnStmts(S->getSynchBody(), hasReturns);
@@ -1663,8 +1680,8 @@ void RewriteObjC::RewriteTryReturnStmts(Stmt *S) {
std::string buf;
buf = "{ objc_exception_try_exit(&_stack); return";
- ReplaceText(startLoc, 6, buf.c_str(), buf.size());
- InsertText(onePastSemiLoc, "}", 1);
+ ReplaceText(startLoc, 6, buf);
+ InsertText(onePastSemiLoc, "}");
}
return;
}
@@ -1689,8 +1706,8 @@ void RewriteObjC::RewriteSyncReturnStmts(Stmt *S, std::string syncExitBuf) {
buf += syncExitBuf;
buf += " return";
- ReplaceText(startLoc, 6, buf.c_str(), buf.size());
- InsertText(onePastSemiLoc, "}", 1);
+ ReplaceText(startLoc, 6, buf);
+ InsertText(onePastSemiLoc, "}");
}
return;
}
@@ -1711,7 +1728,7 @@ Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
buf += "objc_exception_try_enter(&_stack);\n";
buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
- ReplaceText(startLoc, 4, buf.c_str(), buf.size());
+ ReplaceText(startLoc, 4, buf);
startLoc = S->getTryBody()->getLocEnd();
startBuf = SM->getCharacterData(startLoc);
@@ -1729,12 +1746,12 @@ Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
buf += " _rethrow = objc_exception_extract(&_stack);\n";
buf += " else { /* @catch continue */";
- InsertText(startLoc, buf.c_str(), buf.size());
+ InsertText(startLoc, buf);
} else { /* no catch list */
buf = "}\nelse {\n";
buf += " _rethrow = objc_exception_extract(&_stack);\n";
buf += "}";
- ReplaceText(lastCurlyLoc, 1, buf.c_str(), buf.size());
+ ReplaceText(lastCurlyLoc, 1, buf);
}
bool sawIdTypedCatch = false;
Stmt *lastCatchBody = 0;
@@ -1767,7 +1784,7 @@ Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
QualType t = catchDecl->getType();
if (t == Context->getObjCIdType()) {
buf += "1) { ";
- ReplaceText(startLoc, lParenLoc-startBuf+1, buf.c_str(), buf.size());
+ ReplaceText(startLoc, lParenLoc-startBuf+1, buf);
sawIdTypedCatch = true;
} else if (t->isObjCObjectPointerType()) {
QualType InterfaceTy = t->getPointeeType();
@@ -1777,7 +1794,7 @@ Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
buf += "objc_exception_match((struct objc_class *)objc_getClass(\"";
buf += cls->getDecl()->getNameAsString();
buf += "\"), (struct objc_object *)_caught)) { ";
- ReplaceText(startLoc, lParenLoc-startBuf+1, buf.c_str(), buf.size());
+ ReplaceText(startLoc, lParenLoc-startBuf+1, buf);
}
}
// Now rewrite the body...
@@ -1789,10 +1806,9 @@ Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
assert((*rParenBuf == ')') && "bogus @catch paren location");
assert((*bodyBuf == '{') && "bogus @catch body location");
- buf = " = _caught;";
// Here we replace ") {" with "= _caught;" (which initializes and
// declares the @catch parameter).
- ReplaceText(rParenLoc, bodyBuf-rParenBuf+1, buf.c_str(), buf.size());
+ ReplaceText(rParenLoc, bodyBuf-rParenBuf+1, " = _caught;");
} else {
assert(false && "@catch rewrite bug");
}
@@ -1814,7 +1830,7 @@ Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
buf += "} } /* @catch end */\n";
if (!S->getFinallyStmt())
buf += "}\n";
- InsertText(bodyLoc, buf.c_str(), buf.size());
+ InsertText(bodyLoc, buf);
// Set lastCurlyLoc
lastCurlyLoc = lastCatchBody->getLocEnd();
@@ -1824,8 +1840,7 @@ Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
startBuf = SM->getCharacterData(startLoc);
assert((*startBuf == '@') && "bogus @finally start");
- buf = "/* @finally */";
- ReplaceText(startLoc, 8, buf.c_str(), buf.size());
+ ReplaceText(startLoc, 8, "/* @finally */");
Stmt *body = finalStmt->getFinallyBody();
SourceLocation startLoc = body->getLocStart();
@@ -1836,11 +1851,9 @@ Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
"bogus @finally body location");
startLoc = startLoc.getFileLocWithOffset(1);
- buf = " if (!_rethrow) objc_exception_try_exit(&_stack);\n";
- InsertText(startLoc, buf.c_str(), buf.size());
+ InsertText(startLoc, " if (!_rethrow) objc_exception_try_exit(&_stack);\n");
endLoc = endLoc.getFileLocWithOffset(-1);
- buf = " if (_rethrow) objc_exception_throw(_rethrow);\n";
- InsertText(endLoc, buf.c_str(), buf.size());
+ InsertText(endLoc, " if (_rethrow) objc_exception_throw(_rethrow);\n");
// Set lastCurlyLoc
lastCurlyLoc = body->getLocEnd();
@@ -1852,7 +1865,7 @@ Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
buf += " if (!_rethrow) objc_exception_try_exit(&_stack);\n";
buf += " if (_rethrow) objc_exception_throw(_rethrow);\n";
buf += "}";
- ReplaceText(lastCurlyLoc, 1, buf.c_str(), buf.size());
+ ReplaceText(lastCurlyLoc, 1, buf);
// Now check for any return/continue/go statements within the @try.
// The implicit finally clause won't called if the @try contains any
@@ -1864,8 +1877,7 @@ Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
}
// Now emit the final closing curly brace...
lastCurlyLoc = lastCurlyLoc.getFileLocWithOffset(1);
- buf = " } /* @try scope end */\n";
- InsertText(lastCurlyLoc, buf.c_str(), buf.size());
+ InsertText(lastCurlyLoc, " } /* @try scope end */\n");
return 0;
}
@@ -1897,13 +1909,12 @@ Stmt *RewriteObjC::RewriteObjCThrowStmt(ObjCAtThrowStmt *S) {
// handle "@ throw" correctly.
const char *wBuf = strchr(startBuf, 'w');
assert((*wBuf == 'w') && "@throw: can't find 'w'");
- ReplaceText(startLoc, wBuf-startBuf+1, buf.c_str(), buf.size());
+ ReplaceText(startLoc, wBuf-startBuf+1, buf);
const char *semiBuf = strchr(startBuf, ';');
assert((*semiBuf == ';') && "@throw: can't find ';'");
SourceLocation semiLoc = startLoc.getFileLocWithOffset(semiBuf-startBuf);
- buf = ");";
- ReplaceText(semiLoc, 1, buf.c_str(), buf.size());
+ ReplaceText(semiLoc, 1, ");");
return 0;
}
@@ -1991,7 +2002,17 @@ static void scanToNextArgument(const char *&argRef) {
}
bool RewriteObjC::needToScanForQualifiers(QualType T) {
- return T->isObjCQualifiedIdType() || T->isObjCQualifiedInterfaceType();
+ if (T->isObjCQualifiedIdType())
+ return true;
+ if (const PointerType *PT = T->getAs<PointerType>()) {
+ if (PT->getPointeeType()->isObjCQualifiedIdType())
+ return true;
+ }
+ if (T->isObjCObjectPointerType()) {
+ T = T->getPointeeType();
+ return T->isObjCQualifiedInterfaceType();
+ }
+ return false;
}
void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) {
@@ -2018,8 +2039,8 @@ void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) {
SourceLocation LessLoc = Loc.getFileLocWithOffset(startRef-startBuf);
SourceLocation GreaterLoc = Loc.getFileLocWithOffset(endRef-startBuf+1);
// Comment out the protocol references.
- InsertText(LessLoc, "/*", 2);
- InsertText(GreaterLoc, "*/", 2);
+ InsertText(LessLoc, "/*");
+ InsertText(GreaterLoc, "*/");
}
}
}
@@ -2063,8 +2084,8 @@ void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) {
SourceLocation LessLoc = Loc.getFileLocWithOffset(startRef-endBuf);
SourceLocation GreaterLoc = Loc.getFileLocWithOffset(endRef-endBuf+1);
// Comment out the protocol references.
- InsertText(LessLoc, "/*", 2);
- InsertText(GreaterLoc, "*/", 2);
+ InsertText(LessLoc, "/*");
+ InsertText(GreaterLoc, "*/");
}
}
if (!proto)
@@ -2087,8 +2108,8 @@ void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) {
SourceLocation GreaterLoc =
Loc.getFileLocWithOffset(endRef-startFuncBuf+1);
// Comment out the protocol references.
- InsertText(LessLoc, "/*", 2);
- InsertText(GreaterLoc, "*/", 2);
+ InsertText(LessLoc, "/*");
+ InsertText(GreaterLoc, "*/");
}
startBuf = ++endBuf;
}
@@ -2102,6 +2123,42 @@ void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) {
}
}
+void RewriteObjC::RewriteTypeOfDecl(VarDecl *ND) {
+ QualType QT = ND->getType();
+ const Type* TypePtr = QT->getAs<Type>();
+ if (!isa<TypeOfExprType>(TypePtr))
+ return;
+ while (isa<TypeOfExprType>(TypePtr)) {
+ const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
+ QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
+ TypePtr = QT->getAs<Type>();
+ }
+ // FIXME. This will not work for multiple declarators; as in:
+ // __typeof__(a) b,c,d;
+ std::string TypeAsString(QT.getAsString());
+ SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
+ const char *startBuf = SM->getCharacterData(DeclLoc);
+ if (ND->getInit()) {
+ std::string Name(ND->getNameAsString());
+ TypeAsString += " " + Name + " = ";
+ Expr *E = ND->getInit();
+ SourceLocation startLoc;
+ if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E))
+ startLoc = ECE->getLParenLoc();
+ else
+ startLoc = E->getLocStart();
+ startLoc = SM->getInstantiationLoc(startLoc);
+ const char *endBuf = SM->getCharacterData(startLoc);
+ ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
+ }
+ else {
+ SourceLocation X = ND->getLocEnd();
+ X = SM->getInstantiationLoc(X);
+ const char *endBuf = SM->getCharacterData(X);
+ ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
+ }
+}
+
// SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str);
void RewriteObjC::SynthSelGetUidFunctionDecl() {
IdentifierInfo *SelGetUidIdent = &Context->Idents.get("sel_registerName");
@@ -2126,6 +2183,19 @@ void RewriteObjC::RewriteFunctionDecl(FunctionDecl *FD) {
RewriteObjCQualifiedInterfaceTypes(FD);
}
+static void RewriteBlockPointerType(std::string& Str, QualType Type) {
+ std::string TypeString(Type.getAsString());
+ const char *argPtr = TypeString.c_str();
+ if (!strchr(argPtr, '^')) {
+ Str += TypeString;
+ return;
+ }
+ while (*argPtr) {
+ Str += (*argPtr == '^' ? '*' : *argPtr);
+ argPtr++;
+ }
+}
+
void RewriteObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) {
SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
const FunctionType *funcType = FD->getType()->getAs<FunctionType>();
@@ -2140,13 +2210,12 @@ void RewriteObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) {
unsigned numArgs = proto->getNumArgs();
for (unsigned i = 0; i < numArgs; i++) {
QualType ArgType = proto->getArgType(i);
- FdStr += ArgType.getAsString();
-
+ RewriteBlockPointerType(FdStr, ArgType);
if (i+1 < numArgs)
FdStr += ", ";
}
FdStr += ");\n";
- InsertText(FunLocStart, FdStr.c_str(), FdStr.size());
+ InsertText(FunLocStart, FdStr);
CurFunctionDeclToDeclareForBlock = 0;
}
@@ -2330,7 +2399,7 @@ Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
Preamble += utostr(Exp->getString()->getByteLength()) + "};\n";
VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
- &Context->Idents.get(S.c_str()), strType, 0,
+ &Context->Idents.get(S), strType, 0,
VarDecl::Static);
DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, strType, SourceLocation());
Expr *Unop = new (Context) UnaryOperator(DRE, UnaryOperator::AddrOf,
@@ -2380,7 +2449,7 @@ QualType RewriteObjC::getSuperStructType() {
/*Mutable=*/false));
}
- SuperStructDecl->completeDefinition(*Context);
+ SuperStructDecl->completeDefinition();
}
return Context->getTagDeclType(SuperStructDecl);
}
@@ -2411,7 +2480,7 @@ QualType RewriteObjC::getConstantStringStructType() {
/*Mutable=*/true));
}
- ConstantStringDecl->completeDefinition(*Context);
+ ConstantStringDecl->completeDefinition();
}
return Context->getTagDeclType(ConstantStringDecl);
}
@@ -2871,7 +2940,7 @@ void RewriteObjC::SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl,
if ((CDecl->isForwardDecl() || NumIvars == 0) &&
(!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
- ReplaceText(LocStart, endBuf-startBuf, Result.c_str(), Result.size());
+ ReplaceText(LocStart, endBuf-startBuf, Result);
return;
}
@@ -2913,10 +2982,10 @@ void RewriteObjC::SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl,
endHeader++;
}
// rewrite the original header
- ReplaceText(LocStart, endHeader-startBuf, Result.c_str(), Result.size());
+ ReplaceText(LocStart, endHeader-startBuf, Result);
} else {
// rewrite the original header *without* disturbing the '{'
- ReplaceText(LocStart, cursor-startBuf, Result.c_str(), Result.size());
+ ReplaceText(LocStart, cursor-startBuf, Result);
}
if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
Result = "\n struct ";
@@ -2928,7 +2997,7 @@ void RewriteObjC::SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl,
// insert the super class structure definition.
SourceLocation OnePastCurly =
LocStart.getFileLocWithOffset(cursor-startBuf+1);
- InsertText(OnePastCurly, Result.c_str(), Result.size());
+ InsertText(OnePastCurly, Result);
}
cursor++; // past '{'
@@ -2946,26 +3015,26 @@ void RewriteObjC::SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl,
!strncmp(cursor, "private", strlen("private")) ||
!strncmp(cursor, "package", strlen("package")) ||
!strncmp(cursor, "protected", strlen("protected")))
- InsertText(atLoc, "// ", 3);
+ InsertText(atLoc, "// ");
}
// FIXME: If there are cases where '<' is used in ivar declaration part
// of user code, then scan the ivar list and use needToScanForQualifiers
// for type checking.
else if (*cursor == '<') {
SourceLocation atLoc = LocStart.getFileLocWithOffset(cursor-startBuf);
- InsertText(atLoc, "/* ", 3);
+ InsertText(atLoc, "/* ");
cursor = strchr(cursor, '>');
cursor++;
atLoc = LocStart.getFileLocWithOffset(cursor-startBuf);
- InsertText(atLoc, " */", 3);
+ InsertText(atLoc, " */");
} else if (*cursor == '^') { // rewrite block specifier.
SourceLocation caretLoc = LocStart.getFileLocWithOffset(cursor-startBuf);
- ReplaceText(caretLoc, 1, "*", 1);
+ ReplaceText(caretLoc, 1, "*");
}
cursor++;
}
// Don't forget to add a ';'!!
- InsertText(LocEnd.getFileLocWithOffset(1), ";", 1);
+ InsertText(LocEnd.getFileLocWithOffset(1), ";");
} else { // we don't have any instance variables - insert super struct.
endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
Result += " {\n struct ";
@@ -2973,7 +3042,7 @@ void RewriteObjC::SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl,
Result += "_IMPL ";
Result += RCDecl->getNameAsString();
Result += "_IVARS;\n};\n";
- ReplaceText(LocStart, endBuf-startBuf, Result.c_str(), Result.size());
+ ReplaceText(LocStart, endBuf-startBuf, Result);
}
// Mark this struct as having been generated.
if (!ObjCSynthesizedStructs.insert(CDecl))
@@ -3805,7 +3874,7 @@ std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i,
// Create local declarations to avoid rewriting all closure decl ref exprs.
// First, emit a declaration for all "by ref" decls.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
+ for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
E = BlockByRefDecls.end(); I != E; ++I) {
S += " ";
std::string Name = (*I)->getNameAsString();
@@ -3816,7 +3885,7 @@ std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i,
S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n";
}
// Next, emit a declaration for all "by copy" declarations.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
+ for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
E = BlockByCopyDecls.end(); I != E; ++I) {
S += " ";
std::string Name = (*I)->getNameAsString();
@@ -3861,7 +3930,7 @@ std::string RewriteObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
S += (*I)->getNameAsString();
S += ", (void*)src->";
S += (*I)->getNameAsString();
- if (BlockByRefDecls.count((*I)))
+ if (BlockByRefDeclsPtrSet.count((*I)))
S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);";
else
S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);";
@@ -3877,7 +3946,7 @@ std::string RewriteObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
E = ImportedBlockDecls.end(); I != E; ++I) {
S += "_Block_object_dispose((void*)src->";
S += (*I)->getNameAsString();
- if (BlockByRefDecls.count((*I)))
+ if (BlockByRefDeclsPtrSet.count((*I)))
S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);";
else
S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);";
@@ -3901,7 +3970,7 @@ std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag,
if (BlockDeclRefs.size()) {
// Output all "by copy" declarations.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
+ for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
E = BlockByCopyDecls.end(); I != E; ++I) {
S += " ";
std::string FieldName = (*I)->getNameAsString();
@@ -3927,7 +3996,7 @@ std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag,
S += FieldName + ";\n";
}
// Output all "by ref" declarations.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
+ for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
E = BlockByRefDecls.end(); I != E; ++I) {
S += " ";
std::string FieldName = (*I)->getNameAsString();
@@ -3966,7 +4035,7 @@ std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag,
Constructor += " Desc = desc;\n";
// Initialize all "by copy" arguments.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
+ for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
E = BlockByCopyDecls.end(); I != E; ++I) {
std::string Name = (*I)->getNameAsString();
Constructor += " ";
@@ -3977,7 +4046,7 @@ std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag,
Constructor += Name + ";\n";
}
// Initialize all "by ref" arguments.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
+ for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
E = BlockByRefDecls.end(); I != E; ++I) {
std::string Name = (*I)->getNameAsString();
Constructor += " ";
@@ -4047,23 +4116,25 @@ void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);
- InsertText(FunLocStart, CI.c_str(), CI.size());
+ InsertText(FunLocStart, CI);
std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);
- InsertText(FunLocStart, CF.c_str(), CF.size());
+ InsertText(FunLocStart, CF);
if (ImportedBlockDecls.size()) {
std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
- InsertText(FunLocStart, HF.c_str(), HF.size());
+ InsertText(FunLocStart, HF);
}
std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
ImportedBlockDecls.size() > 0);
- InsertText(FunLocStart, BD.c_str(), BD.size());
+ InsertText(FunLocStart, BD);
BlockDeclRefs.clear();
BlockByRefDecls.clear();
+ BlockByRefDeclsPtrSet.clear();
BlockByCopyDecls.clear();
+ BlockByCopyDeclsPtrSet.clear();
BlockCallExprs.clear();
ImportedBlockDecls.clear();
}
@@ -4078,17 +4149,23 @@ void RewriteObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) {
SynthesizeBlockLiterals(FunLocStart, FuncName);
}
-void RewriteObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) {
- //fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n");
- //SourceLocation FunLocStart = MD->getLocStart();
- // FIXME: This hack works around a bug in Rewrite.InsertText().
- SourceLocation FunLocStart = MD->getLocStart().getFileLocWithOffset(-1);
- std::string FuncName = MD->getSelector().getAsString();
+static void BuildUniqueMethodName(std::string &Name,
+ ObjCMethodDecl *MD) {
+ ObjCInterfaceDecl *IFace = MD->getClassInterface();
+ Name = IFace->getNameAsCString();
+ Name += "__" + MD->getSelector().getAsString();
// Convert colons to underscores.
std::string::size_type loc = 0;
- while ((loc = FuncName.find(":", loc)) != std::string::npos)
- FuncName.replace(loc, 1, "_");
+ while ((loc = Name.find(":", loc)) != std::string::npos)
+ Name.replace(loc, 1, "_");
+}
+void RewriteObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) {
+ //fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n");
+ //SourceLocation FunLocStart = MD->getLocStart();
+ SourceLocation FunLocStart = MD->getLocStart();
+ std::string FuncName;
+ BuildUniqueMethodName(FuncName, MD);
SynthesizeBlockLiterals(FunLocStart, FuncName.c_str());
}
@@ -4304,11 +4381,9 @@ void RewriteObjC::RewriteCastExpr(CStyleCastExpr *CE) {
std::string TypeAsString = "(";
TypeAsString += QT.getAsString();
TypeAsString += ")";
- ReplaceText(LocStart, endBuf-startBuf+1,
- TypeAsString.c_str(), TypeAsString.size());
+ ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
return;
}
-
// advance the location to startArgList.
const char *argPtr = startBuf;
@@ -4317,7 +4392,7 @@ void RewriteObjC::RewriteCastExpr(CStyleCastExpr *CE) {
case '^':
// Replace the '^' with '*'.
LocStart = LocStart.getFileLocWithOffset(argPtr-startBuf);
- ReplaceText(LocStart, 1, "*", 1);
+ ReplaceText(LocStart, 1, "*");
break;
}
}
@@ -4346,7 +4421,7 @@ void RewriteObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) {
case '^':
// Replace the '^' with '*'.
DeclLoc = DeclLoc.getFileLocWithOffset(argPtr-startArgList);
- ReplaceText(DeclLoc, 1, "*", 1);
+ ReplaceText(DeclLoc, 1, "*");
break;
case '(':
parenCount++;
@@ -4427,7 +4502,7 @@ void RewriteObjC::RewriteBlockPointerDecl(NamedDecl *ND) {
if (*startBuf == '^') {
// Replace the '^' with '*', computing a negative offset.
DeclLoc = DeclLoc.getFileLocWithOffset(startBuf-endBuf);
- ReplaceText(DeclLoc, 1, "*", 1);
+ ReplaceText(DeclLoc, 1, "*");
}
if (PointerTypeTakesAnyBlockArguments(DeclT)) {
// Replace the '^' with '*' for arguments.
@@ -4438,7 +4513,7 @@ void RewriteObjC::RewriteBlockPointerDecl(NamedDecl *ND) {
while (argListBegin < argListEnd) {
if (*argListBegin == '^') {
SourceLocation CaretLoc = DeclLoc.getFileLocWithOffset(argListBegin-startBuf);
- ReplaceText(CaretLoc, 1, "*", 1);
+ ReplaceText(CaretLoc, 1, "*");
}
argListBegin++;
}
@@ -4563,7 +4638,7 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) {
assert(CurMethodDef && "RewriteByRefVar - CurMethodDef is null");
FunLocStart = CurMethodDef->getLocStart();
}
- InsertText(FunLocStart, ByrefType.c_str(), ByrefType.size());
+ InsertText(FunLocStart, ByrefType);
if (Ty.isObjCGCWeak()) {
flag |= BLOCK_FIELD_IS_WEAK;
isa = 1;
@@ -4579,7 +4654,7 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) {
flag |= BLOCK_FIELD_IS_OBJECT;
std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
if (!HF.empty())
- InsertText(FunLocStart, HF.c_str(), HF.size());
+ InsertText(FunLocStart, HF);
}
// struct __Block_byref_ND ND =
@@ -4592,10 +4667,12 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) {
Name = ND->getNameAsString();
ByrefType.clear();
RewriteByRefString(ByrefType, Name, ND);
+ std::string ForwardingCastType("(");
+ ForwardingCastType += ByrefType + " *)";
if (!hasInit) {
ByrefType += " " + Name + " = {(void*)";
ByrefType += utostr(isa);
- ByrefType += ", &" + Name + ", ";
+ ByrefType += "," + ForwardingCastType + "&" + Name + ", ";
ByrefType += utostr(flags);
ByrefType += ", ";
ByrefType += "sizeof(";
@@ -4608,8 +4685,7 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) {
ByrefType += utostr(flag);
}
ByrefType += "};\n";
- ReplaceText(DeclLoc, endBuf-startBuf+Name.size(),
- ByrefType.c_str(), ByrefType.size());
+ ReplaceText(DeclLoc, endBuf-startBuf+Name.size(), ByrefType);
}
else {
SourceLocation startLoc;
@@ -4624,7 +4700,7 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) {
ByrefType += " " + Name;
ByrefType += " = {(void*)";
ByrefType += utostr(isa);
- ByrefType += ", &" + Name + ", ";
+ ByrefType += "," + ForwardingCastType + "&" + Name + ", ";
ByrefType += utostr(flags);
ByrefType += ", ";
ByrefType += "sizeof(";
@@ -4637,8 +4713,7 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) {
ByrefType += utostr(flag);
ByrefType += ", ";
}
- ReplaceText(DeclLoc, endBuf-startBuf,
- ByrefType.c_str(), ByrefType.size());
+ ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
// Complete the newly synthesized compound expression by inserting a right
// curly brace before the end of the declaration.
@@ -4654,7 +4729,7 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) {
SourceLocation semiLoc =
startLoc.getFileLocWithOffset(semiBuf-startBuf);
- InsertText(semiLoc, "}", 1);
+ InsertText(semiLoc, "}");
}
return;
}
@@ -4665,12 +4740,19 @@ void RewriteObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) {
if (BlockDeclRefs.size()) {
// Unique all "by copy" declarations.
for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
- if (!BlockDeclRefs[i]->isByRef())
- BlockByCopyDecls.insert(BlockDeclRefs[i]->getDecl());
+ if (!BlockDeclRefs[i]->isByRef()) {
+ if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
+ BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
+ BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
+ }
+ }
// Unique all "by ref" declarations.
for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
if (BlockDeclRefs[i]->isByRef()) {
- BlockByRefDecls.insert(BlockDeclRefs[i]->getDecl());
+ if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
+ BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
+ BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
+ }
}
// Find any imported blocks...they will need special attention.
for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
@@ -4699,13 +4781,9 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp) {
if (CurFunctionDef)
FuncName = CurFunctionDef->getNameAsString();
- else if (CurMethodDef) {
- FuncName = CurMethodDef->getSelector().getAsString();
- // Convert colons to underscores.
- std::string::size_type loc = 0;
- while ((loc = FuncName.find(":", loc)) != std::string::npos)
- FuncName.replace(loc, 1, "_");
- } else if (GlobalVarDecl)
+ else if (CurMethodDef)
+ BuildUniqueMethodName(FuncName, CurMethodDef);
+ else if (GlobalVarDecl)
FuncName = std::string(GlobalVarDecl->getNameAsString());
std::string BlockNumber = utostr(Blocks.size()-1);
@@ -4752,7 +4830,7 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp) {
if (BlockDeclRefs.size()) {
Expr *Exp;
// Output all "by copy" declarations.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
+ for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
E = BlockByCopyDecls.end(); I != E; ++I) {
if (isObjCType((*I)->getType())) {
// FIXME: Conform to ABI ([[obj retain] autorelease]).
@@ -4770,13 +4848,25 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp) {
InitExprs.push_back(Exp);
}
// Output all "by ref" declarations.
- for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
+ for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
E = BlockByRefDecls.end(); I != E; ++I) {
+ ValueDecl *ND = (*I);
+ std::string Name(ND->getNameAsString());
+ std::string RecName;
+ RewriteByRefString(RecName, Name, ND);
+ IdentifierInfo *II = &Context->Idents.get(RecName.c_str()
+ + sizeof("struct"));
+ RecordDecl *RD = RecordDecl::Create(*Context, TagDecl::TK_struct, TUDecl,
+ SourceLocation(), II);
+ assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl");
+ QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
+
FD = SynthBlockInitFunctionDecl((*I)->getNameAsCString());
Exp = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation());
Exp = new (Context) UnaryOperator(Exp, UnaryOperator::AddrOf,
Context->getPointerType(Exp->getType()),
SourceLocation());
+ Exp = NoTypeInfoCStyleCastExpr(Context, castT, CastExpr::CK_Unknown, Exp);
InitExprs.push_back(Exp);
}
}
@@ -4798,7 +4888,9 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp) {
NewRep);
BlockDeclRefs.clear();
BlockByRefDecls.clear();
+ BlockByRefDeclsPtrSet.clear();
BlockByCopyDecls.clear();
+ BlockByCopyDeclsPtrSet.clear();
ImportedBlockDecls.clear();
return NewRep;
}
@@ -4843,7 +4935,21 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
for (Stmt::child_iterator CI = S->child_begin(), E = S->child_end();
CI != E; ++CI)
if (*CI) {
- Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(*CI);
+ Stmt *newStmt;
+ Stmt *S = (*CI);
+ if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
+ Expr *OldBase = IvarRefExpr->getBase();
+ bool replaced = false;
+ newStmt = RewriteObjCNestedIvarRefExpr(S, replaced);
+ if (replaced) {
+ if (ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(newStmt))
+ ReplaceStmt(OldBase, IRE->getBase());
+ else
+ ReplaceStmt(S, newStmt);
+ }
+ }
+ else
+ newStmt = RewriteFunctionBodyOrGlobalInitializer(S);
if (newStmt)
*CI = newStmt;
}
@@ -4865,9 +4971,6 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S))
return RewriteAtEncode(AtEncode);
- if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S))
- return RewriteObjCIvarRefExpr(IvarRefExpr, OrigStmtRange.getBegin());
-
if (ObjCPropertyRefExpr *PropRefExpr = dyn_cast<ObjCPropertyRefExpr>(S)) {
BinaryOperator *BinOp = PropSetters[PropRefExpr];
if (BinOp) {
@@ -4995,7 +5098,7 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
RewriteBlockPointerDecl(ND);
else if (ND->getType()->isFunctionPointerType())
CheckFunctionPointerDecl(ND->getType(), ND);
- if (VarDecl *VD = dyn_cast<VarDecl>(SD))
+ if (VarDecl *VD = dyn_cast<VarDecl>(SD)) {
if (VD->hasAttr<BlocksAttr>()) {
static unsigned uniqueByrefDeclCount = 0;
assert(!BlockByRefDeclNo.count(ND) &&
@@ -5003,6 +5106,9 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
RewriteByRefVar(VD);
}
+ else
+ RewriteTypeOfDecl(VD);
+ }
}
if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) {
if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
@@ -5191,11 +5297,6 @@ void RewriteObjC::HandleDeclInMainFile(Decl *D) {
}
void RewriteObjC::HandleTranslationUnit(ASTContext &C) {
- // Get the top-level buffer that this corresponds to.
-
- // Rewrite tabs if we care.
- //RewriteTabs();
-
if (Diags.hasErrorOccurred())
return;
@@ -5207,8 +5308,7 @@ void RewriteObjC::HandleTranslationUnit(ASTContext &C) {
E = ProtocolExprDecls.end(); I != E; ++I)
RewriteObjCProtocolMetaData(*I, "", "", Preamble);
- InsertText(SM->getLocForStartOfFile(MainFileID),
- Preamble.c_str(), Preamble.size(), false);
+ InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false);
if (ClassImplementation.size() || CategoryImplementation.size())
RewriteImplementations();
@@ -5219,7 +5319,7 @@ void RewriteObjC::HandleTranslationUnit(ASTContext &C) {
//printf("Changed:\n");
*OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
} else {
- fprintf(stderr, "No changes\n");
+ llvm::errs() << "No changes\n";
}
if (ClassImplementation.size() || CategoryImplementation.size() ||
diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp
index 83b4542..9ec5ffe 100644
--- a/lib/Frontend/TextDiagnosticPrinter.cpp
+++ b/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -104,11 +104,6 @@ void TextDiagnosticPrinter::HighlightRange(const SourceRange &R,
if (StartColNo) --StartColNo; // Zero base the col #.
}
- // Pick the first non-whitespace column.
- while (StartColNo < SourceLine.size() &&
- (SourceLine[StartColNo] == ' ' || SourceLine[StartColNo] == '\t'))
- ++StartColNo;
-
// Compute the column number of the end.
unsigned EndColNo = CaretLine.size();
if (EndLineNo == LineNo) {
@@ -123,16 +118,25 @@ void TextDiagnosticPrinter::HighlightRange(const SourceRange &R,
}
}
+ assert(StartColNo <= EndColNo && "Invalid range!");
+
+ // Pick the first non-whitespace column.
+ while (StartColNo < SourceLine.size() &&
+ (SourceLine[StartColNo] == ' ' || SourceLine[StartColNo] == '\t'))
+ ++StartColNo;
+
// Pick the last non-whitespace column.
- if (EndColNo <= SourceLine.size())
- while (EndColNo-1 &&
- (SourceLine[EndColNo-1] == ' ' || SourceLine[EndColNo-1] == '\t'))
- --EndColNo;
- else
+ if (EndColNo > SourceLine.size())
EndColNo = SourceLine.size();
+ while (EndColNo-1 &&
+ (SourceLine[EndColNo-1] == ' ' || SourceLine[EndColNo-1] == '\t'))
+ --EndColNo;
+
+ // If the start/end passed each other, then we are trying to highlight a range
+ // that just exists in whitespace, which must be some sort of other bug.
+ assert(StartColNo <= EndColNo && "Trying to highlight whitespace??");
// Fill the range with ~'s.
- assert(StartColNo <= EndColNo && "Invalid range!");
for (unsigned i = StartColNo; i < EndColNo; ++i)
CaretLine[i] = '~';
}
OpenPOWER on IntegriCloud