aboutsummaryrefslogtreecommitdiff
path: root/lib/Frontend
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2010-05-04 16:12:48 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2010-05-04 16:12:48 +0000
commit0883ccd9eac3b974df00e6548ee319a7dd3646f4 (patch)
treed6a70c3518b8dea8be7062438d7e8676820ed17f /lib/Frontend
parent60bfabcd8ce617297c0d231f77d14ab507e98796 (diff)
downloadsrc-0883ccd9eac3b974df00e6548ee319a7dd3646f4.tar.gz
src-0883ccd9eac3b974df00e6548ee319a7dd3646f4.zip
Notes
Diffstat (limited to 'lib/Frontend')
-rw-r--r--lib/Frontend/ASTConsumers.cpp191
-rw-r--r--lib/Frontend/ASTUnit.cpp18
-rw-r--r--lib/Frontend/AnalysisConsumer.cpp209
-rw-r--r--lib/Frontend/CacheTokens.cpp5
-rw-r--r--lib/Frontend/CodeGenAction.cpp313
-rw-r--r--lib/Frontend/CompilerInstance.cpp19
-rw-r--r--lib/Frontend/CompilerInvocation.cpp135
-rw-r--r--lib/Frontend/FixItRewriter.cpp105
-rw-r--r--lib/Frontend/FrontendActions.cpp71
-rw-r--r--lib/Frontend/InitHeaderSearch.cpp59
-rw-r--r--lib/Frontend/InitPreprocessor.cpp30
-rw-r--r--lib/Frontend/LangStandards.cpp2
-rw-r--r--lib/Frontend/PCHReader.cpp34
-rw-r--r--lib/Frontend/PCHReaderDecl.cpp17
-rw-r--r--lib/Frontend/PCHReaderStmt.cpp135
-rw-r--r--lib/Frontend/PCHWriter.cpp15
-rw-r--r--lib/Frontend/PCHWriterDecl.cpp10
-rw-r--r--lib/Frontend/PCHWriterStmt.cpp83
-rw-r--r--lib/Frontend/PrintParserCallbacks.cpp9
-rw-r--r--lib/Frontend/PrintPreprocessedOutput.cpp50
-rw-r--r--lib/Frontend/RewriteMacros.cpp3
-rw-r--r--lib/Frontend/RewriteObjC.cpp528
-rw-r--r--lib/Frontend/StmtXML.cpp5
-rw-r--r--lib/Frontend/TextDiagnosticPrinter.cpp24
-rw-r--r--lib/Frontend/VerifyDiagnosticsClient.cpp463
-rw-r--r--lib/Frontend/Warnings.cpp6
26 files changed, 1461 insertions, 1078 deletions
diff --git a/lib/Frontend/ASTConsumers.cpp b/lib/Frontend/ASTConsumers.cpp
index ebbd720ceb63..7b8ebf92032e 100644
--- a/lib/Frontend/ASTConsumers.cpp
+++ b/lib/Frontend/ASTConsumers.cpp
@@ -24,7 +24,6 @@
#include "clang/AST/PrettyPrinter.h"
#include "clang/CodeGen/ModuleBuilder.h"
#include "llvm/Module.h"
-#include "llvm/Support/Format.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Path.h"
@@ -165,7 +164,7 @@ void DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
case Decl::Namespace: {
Out << "[namespace] ";
const NamespaceDecl* ND = cast<NamespaceDecl>(DC);
- Out << ND->getNameAsString();
+ Out << ND;
break;
}
case Decl::Enum: {
@@ -174,7 +173,7 @@ void DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
Out << "[enum] ";
else
Out << "<enum> ";
- Out << ED->getNameAsString();
+ Out << ED;
break;
}
case Decl::Record: {
@@ -183,7 +182,7 @@ void DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
Out << "[struct] ";
else
Out << "<struct> ";
- Out << RD->getNameAsString();
+ Out << RD;
break;
}
case Decl::CXXRecord: {
@@ -192,7 +191,7 @@ void DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
Out << "[class] ";
else
Out << "<class> ";
- Out << RD->getNameAsString() << " " << DC;
+ Out << RD << ' ' << DC;
break;
}
case Decl::ObjCMethod:
@@ -225,7 +224,7 @@ void DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
Out << "[function] ";
else
Out << "<function> ";
- Out << FD->getNameAsString();
+ Out << FD;
// Print the parameters.
Out << "(";
bool PrintComma = false;
@@ -235,7 +234,7 @@ void DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
Out << ", ";
else
PrintComma = true;
- Out << (*I)->getNameAsString();
+ Out << *I;
}
Out << ")";
break;
@@ -248,7 +247,7 @@ void DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
Out << "(c++ method) ";
else
Out << "<c++ method> ";
- Out << D->getNameAsString();
+ Out << D;
// Print the parameters.
Out << "(";
bool PrintComma = false;
@@ -258,7 +257,7 @@ void DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
Out << ", ";
else
PrintComma = true;
- Out << (*I)->getNameAsString();
+ Out << *I;
}
Out << ")";
@@ -278,7 +277,7 @@ void DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
Out << "(c++ ctor) ";
else
Out << "<c++ ctor> ";
- Out << D->getNameAsString();
+ Out << D;
// Print the parameters.
Out << "(";
bool PrintComma = false;
@@ -288,7 +287,7 @@ void DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
Out << ", ";
else
PrintComma = true;
- Out << (*I)->getNameAsString();
+ Out << *I;
}
Out << ")";
@@ -307,7 +306,7 @@ void DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
Out << "(c++ dtor) ";
else
Out << "<c++ dtor> ";
- Out << D->getNameAsString();
+ Out << D;
// Check the semantic DC.
const DeclContext* SemaDC = D->getDeclContext();
const DeclContext* LexicalDC = D->getLexicalDeclContext();
@@ -323,7 +322,7 @@ void DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
Out << "(c++ conversion) ";
else
Out << "<c++ conversion> ";
- Out << D->getNameAsString();
+ Out << D;
// Check the semantic DC.
const DeclContext* SemaDC = D->getDeclContext();
const DeclContext* LexicalDC = D->getLexicalDeclContext();
@@ -370,42 +369,42 @@ void DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
}
case Decl::Field: {
FieldDecl* FD = cast<FieldDecl>(*I);
- Out << "<field> " << FD->getNameAsString() << "\n";
+ Out << "<field> " << FD << '\n';
break;
}
case Decl::Typedef: {
TypedefDecl* TD = cast<TypedefDecl>(*I);
- Out << "<typedef> " << TD->getNameAsString() << "\n";
+ Out << "<typedef> " << TD << '\n';
break;
}
case Decl::EnumConstant: {
EnumConstantDecl* ECD = cast<EnumConstantDecl>(*I);
- Out << "<enum constant> " << ECD->getNameAsString() << "\n";
+ Out << "<enum constant> " << ECD << '\n';
break;
}
case Decl::Var: {
VarDecl* VD = cast<VarDecl>(*I);
- Out << "<var> " << VD->getNameAsString() << "\n";
+ Out << "<var> " << VD << '\n';
break;
}
case Decl::ImplicitParam: {
ImplicitParamDecl* IPD = cast<ImplicitParamDecl>(*I);
- Out << "<implicit parameter> " << IPD->getNameAsString() << "\n";
+ Out << "<implicit parameter> " << IPD << '\n';
break;
}
case Decl::ParmVar: {
ParmVarDecl* PVD = cast<ParmVarDecl>(*I);
- Out << "<parameter> " << PVD->getNameAsString() << "\n";
+ Out << "<parameter> " << PVD << '\n';
break;
}
case Decl::ObjCProperty: {
ObjCPropertyDecl* OPD = cast<ObjCPropertyDecl>(*I);
- Out << "<objc property> " << OPD->getNameAsString() << "\n";
+ Out << "<objc property> " << OPD << '\n';
break;
}
case Decl::FunctionTemplate: {
FunctionTemplateDecl* FTD = cast<FunctionTemplateDecl>(*I);
- Out << "<function template> " << FTD->getNameAsString() << "\n";
+ Out << "<function template> " << FTD << '\n';
break;
}
case Decl::FileScopeAsm: {
@@ -418,16 +417,16 @@ void DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
}
case Decl::NamespaceAlias: {
NamespaceAliasDecl* NAD = cast<NamespaceAliasDecl>(*I);
- Out << "<namespace alias> " << NAD->getNameAsString() << "\n";
+ Out << "<namespace alias> " << NAD << '\n';
break;
}
case Decl::ClassTemplate: {
ClassTemplateDecl *CTD = cast<ClassTemplateDecl>(*I);
- Out << "<class template> " << CTD->getNameAsString() << '\n';
+ Out << "<class template> " << CTD << '\n';
break;
}
default:
- Out << "DeclKind: " << DK << '"' << I->getDeclKindName() << "\"\n";
+ Out << "DeclKind: " << DK << '"' << *I << "\"\n";
assert(0 && "decl unhandled");
}
}
@@ -437,150 +436,6 @@ ASTConsumer *clang::CreateDeclContextPrinter() {
}
//===----------------------------------------------------------------------===//
-/// RecordLayoutDumper - C++ Record Layout Dumping.
-namespace {
-class RecordLayoutDumper : public ASTConsumer {
- llvm::raw_ostream& Out;
-
- void PrintOffset(uint64_t Offset, unsigned IndentLevel) {
- Out << llvm::format("%4d | ", Offset);
- for (unsigned I = 0; I < IndentLevel * 2; ++I) Out << ' ';
- }
-
- void DumpRecordLayoutOffsets(const CXXRecordDecl *RD, ASTContext &C,
- uint64_t Offset,
- unsigned IndentLevel, const char* Description,
- bool IncludeVirtualBases) {
- const ASTRecordLayout &Info = C.getASTRecordLayout(RD);
-
- PrintOffset(Offset, IndentLevel);
- Out << C.getTypeDeclType((CXXRecordDecl *)RD).getAsString();
- if (Description)
- Out << ' ' << Description;
- if (RD->isEmpty())
- Out << " (empty)";
- Out << '\n';
-
- IndentLevel++;
-
- const CXXRecordDecl *PrimaryBase = Info.getPrimaryBase();
-
- // Vtable pointer.
- if (RD->isDynamicClass() && !PrimaryBase) {
- PrintOffset(Offset, IndentLevel);
- Out << '(' << RD->getNameAsString() << " vtable pointer)\n";
- }
- // Dump (non-virtual) bases
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
- assert(!I->getType()->isDependentType() &&
- "Cannot layout class with dependent bases.");
- if (I->isVirtual())
- continue;
-
- const CXXRecordDecl *Base =
- cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
-
- uint64_t BaseOffset = Offset + Info.getBaseClassOffset(Base) / 8;
-
- DumpRecordLayoutOffsets(Base, C, BaseOffset, IndentLevel,
- Base == PrimaryBase ? "(primary base)" : "(base)",
- /*IncludeVirtualBases=*/false);
- }
-
- // Dump fields.
- uint64_t FieldNo = 0;
- for (CXXRecordDecl::field_iterator I = RD->field_begin(),
- E = RD->field_end(); I != E; ++I, ++FieldNo) {
- const FieldDecl *Field = *I;
- uint64_t FieldOffset = Offset + Info.getFieldOffset(FieldNo) / 8;
-
- if (const RecordType *RT = Field->getType()->getAs<RecordType>()) {
- if (const CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
- DumpRecordLayoutOffsets(D, C, FieldOffset, IndentLevel,
- Field->getNameAsCString(),
- /*IncludeVirtualBases=*/true);
- continue;
- }
- }
-
- PrintOffset(FieldOffset, IndentLevel);
- Out << Field->getType().getAsString() << ' ';
- Out << Field->getNameAsString() << '\n';
- }
-
- if (!IncludeVirtualBases)
- return;
-
- // Dump virtual bases.
- for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
- E = RD->vbases_end(); I != E; ++I) {
- assert(I->isVirtual() && "Found non-virtual class!");
- const CXXRecordDecl *VBase =
- cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
-
- uint64_t VBaseOffset = Offset + Info.getVBaseClassOffset(VBase) / 8;
- DumpRecordLayoutOffsets(VBase, C, VBaseOffset, IndentLevel,
- VBase == PrimaryBase ?
- "(primary virtual base)" : "(virtual base)",
- /*IncludeVirtualBases=*/false);
- }
- }
-
- // FIXME: Maybe this could be useful in ASTContext.cpp.
- void DumpRecordLayout(const CXXRecordDecl *RD, ASTContext &C) {
- const ASTRecordLayout &Info = C.getASTRecordLayout(RD);
-
- DumpRecordLayoutOffsets(RD, C, 0, 0, 0,
- /*IncludeVirtualBases=*/true);
- Out << " sizeof=" << Info.getSize() / 8;
- Out << ", dsize=" << Info.getDataSize() / 8;
- Out << ", align=" << Info.getAlignment() / 8 << '\n';
- Out << " nvsize=" << Info.getNonVirtualSize() / 8;
- Out << ", nvalign=" << Info.getNonVirtualAlign() / 8 << '\n';
- Out << '\n';
- }
-
-public:
- RecordLayoutDumper() : Out(llvm::errs()) {}
-
- void HandleTranslationUnit(ASTContext &C) {
- for (ASTContext::type_iterator I = C.types_begin(), E = C.types_end();
- I != E; ++I) {
- const RecordType *RT = dyn_cast<RecordType>(*I);
- if (!RT)
- continue;
-
- const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
- if (!RD)
- continue;
-
- if (RD->isImplicit())
- continue;
-
- if (RD->isDependentType())
- continue;
-
- if (RD->isInvalidDecl())
- continue;
-
- if (!RD->getDefinition())
- continue;
-
- // FIXME: Do we really need to hard code this?
- if (RD->getQualifiedNameAsString() == "__va_list_tag")
- continue;
-
- DumpRecordLayout(RD, C);
- }
- }
-};
-} // end anonymous namespace
-ASTConsumer *clang::CreateRecordLayoutDumper() {
- return new RecordLayoutDumper();
-}
-
-//===----------------------------------------------------------------------===//
/// InheritanceViewer - C++ Inheritance Visualization
namespace {
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index 427bd6a9b803..4730bdc2f161 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -265,8 +265,16 @@ public:
TopLevelDeclTrackerConsumer(ASTUnit &_Unit) : Unit(_Unit) {}
void HandleTopLevelDecl(DeclGroupRef D) {
- for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it)
- Unit.getTopLevelDecls().push_back(*it);
+ for (DeclGroupRef::iterator it = D.begin(), ie = D.end(); it != ie; ++it) {
+ Decl *D = *it;
+ // FIXME: Currently ObjC method declarations are incorrectly being
+ // reported as top-level declarations, even though their DeclContext
+ // is the containing ObjC @interface/@implementation. This is a
+ // fundamental problem in the parser right now.
+ if (isa<ObjCMethodDecl>(D))
+ continue;
+ Unit.getTopLevelDecls().push_back(D);
+ }
}
};
@@ -431,8 +439,10 @@ ASTUnit *ASTUnit::LoadFromCommandLine(const char **ArgBegin,
const driver::ArgStringList &CCArgs = Cmd->getArguments();
llvm::OwningPtr<CompilerInvocation> CI(new CompilerInvocation);
- CompilerInvocation::CreateFromArgs(*CI, (const char**) CCArgs.data(),
- (const char**) CCArgs.data()+CCArgs.size(),
+ CompilerInvocation::CreateFromArgs(*CI,
+ const_cast<const char **>(CCArgs.data()),
+ const_cast<const char **>(CCArgs.data()) +
+ CCArgs.size(),
*Diags);
// Override any files that need remapping
diff --git a/lib/Frontend/AnalysisConsumer.cpp b/lib/Frontend/AnalysisConsumer.cpp
index d764fd078968..87c3fca24962 100644
--- a/lib/Frontend/AnalysisConsumer.cpp
+++ b/lib/Frontend/AnalysisConsumer.cpp
@@ -41,10 +41,6 @@ using namespace clang;
static ExplodedNode::Auditor* CreateUbiViz();
//===----------------------------------------------------------------------===//
-// Basic type definitions.
-//===----------------------------------------------------------------------===//
-
-//===----------------------------------------------------------------------===//
// Special PathDiagnosticClients.
//===----------------------------------------------------------------------===//
@@ -62,20 +58,21 @@ CreatePlistHTMLDiagnosticClient(const std::string& prefix,
namespace {
- class AnalysisConsumer : public ASTConsumer {
- public:
+class AnalysisConsumer : public ASTConsumer {
+public:
typedef void (*CodeAction)(AnalysisConsumer &C, AnalysisManager &M, Decl *D);
typedef void (*TUAction)(AnalysisConsumer &C, AnalysisManager &M,
TranslationUnitDecl &TU);
- private:
+private:
typedef std::vector<CodeAction> Actions;
typedef std::vector<TUAction> TUActions;
Actions FunctionActions;
Actions ObjCMethodActions;
Actions ObjCImplementationActions;
- TUActions TranslationUnitActions;
+ Actions CXXMethodActions;
+ TUActions TranslationUnitActions; // Remove this.
public:
ASTContext* Ctx;
@@ -150,7 +147,7 @@ public:
if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
const NamedDecl *ND = cast<NamedDecl>(D);
- llvm::errs() << ' ' << ND->getNameAsString() << '\n';
+ llvm::errs() << ' ' << ND << '\n';
}
else if (isa<BlockDecl>(D)) {
llvm::errs() << ' ' << "block(line:" << Loc.getLine() << ",col:"
@@ -161,103 +158,100 @@ public:
void addCodeAction(CodeAction action) {
FunctionActions.push_back(action);
ObjCMethodActions.push_back(action);
- }
-
- void addObjCImplementationAction(CodeAction action) {
- ObjCImplementationActions.push_back(action);
+ CXXMethodActions.push_back(action);
}
void addTranslationUnitAction(TUAction action) {
TranslationUnitActions.push_back(action);
}
+ void addObjCImplementationAction(CodeAction action) {
+ ObjCImplementationActions.push_back(action);
+ }
+
virtual void Initialize(ASTContext &Context) {
Ctx = &Context;
Mgr.reset(new AnalysisManager(*Ctx, PP.getDiagnostics(),
PP.getLangOptions(), PD,
CreateStoreMgr, CreateConstraintMgr,
+ Opts.MaxNodes,
Opts.VisualizeEGDot, Opts.VisualizeEGUbi,
Opts.PurgeDead, Opts.EagerlyAssume,
Opts.TrimGraph));
}
- virtual void HandleTopLevelDecl(DeclGroupRef D) {
- declDisplayed = false;
- for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
- HandleTopLevelSingleDecl(*I);
- }
-
- void HandleTopLevelSingleDecl(Decl *D);
virtual void HandleTranslationUnit(ASTContext &C);
-
- void HandleCode(Decl* D, Stmt* Body, Actions& actions);
+ void HandleCode(Decl *D, Stmt* Body, Actions& actions);
};
} // end anonymous namespace
-namespace llvm {
- template <> struct FoldingSetTrait<AnalysisConsumer::CodeAction> {
- static inline void Profile(AnalysisConsumer::CodeAction X,
- FoldingSetNodeID& ID) {
- ID.AddPointer(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(X)));
- }
- };
-}
-
//===----------------------------------------------------------------------===//
// AnalysisConsumer implementation.
//===----------------------------------------------------------------------===//
-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() &&
- FD->getDeclName().getAsString() != Opts.AnalyzeSpecificFunction)
- break;
-
- if (Stmt *Body = FD->getBody())
- HandleCode(FD, Body, FunctionActions);
- break;
- }
-
- case Decl::ObjCMethod: {
- ObjCMethodDecl* MD = cast<ObjCMethodDecl>(D);
+void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
- if (!Opts.AnalyzeSpecificFunction.empty() &&
- Opts.AnalyzeSpecificFunction != MD->getSelector().getAsString())
- return;
+ TranslationUnitDecl *TU = C.getTranslationUnitDecl();
- if (Stmt* Body = MD->getBody())
- HandleCode(MD, Body, ObjCMethodActions);
- break;
- }
+ for (DeclContext::decl_iterator I = TU->decls_begin(), E = TU->decls_end();
+ I != E; ++I) {
+ Decl *D = *I;
+
+ switch (D->getKind()) {
+ case Decl::CXXConstructor:
+ case Decl::CXXDestructor:
+ case Decl::CXXConversion:
+ case Decl::CXXMethod:
+ case Decl::Function: {
+ FunctionDecl* FD = cast<FunctionDecl>(D);
+
+ if (FD->isThisDeclarationADefinition()) {
+ if (!Opts.AnalyzeSpecificFunction.empty() &&
+ FD->getDeclName().getAsString() != Opts.AnalyzeSpecificFunction)
+ break;
+ HandleCode(FD, FD->getBody(), FunctionActions);
+ }
+ break;
+ }
- default:
- break;
- }
-}
+ case Decl::ObjCMethod: {
+ ObjCMethodDecl* MD = cast<ObjCMethodDecl>(D);
+
+ if (MD->isThisDeclarationADefinition()) {
+ if (!Opts.AnalyzeSpecificFunction.empty() &&
+ Opts.AnalyzeSpecificFunction != MD->getSelector().getAsString())
+ break;
+ HandleCode(MD, MD->getBody(), ObjCMethodActions);
+ }
+ break;
+ }
-void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
+ case Decl::ObjCImplementation: {
+ ObjCImplementationDecl* ID = cast<ObjCImplementationDecl>(*I);
+ HandleCode(ID, 0, ObjCImplementationActions);
+
+ for (ObjCImplementationDecl::method_iterator MI = ID->meth_begin(),
+ ME = ID->meth_end(); MI != ME; ++MI) {
+ if ((*MI)->isThisDeclarationADefinition()) {
+ if (!Opts.AnalyzeSpecificFunction.empty() &&
+ Opts.AnalyzeSpecificFunction != (*MI)->getSelector().getAsString())
+ break;
+ HandleCode(*MI, (*MI)->getBody(), ObjCMethodActions);
+ }
+ }
+ break;
+ }
- TranslationUnitDecl *TU = C.getTranslationUnitDecl();
+ default:
+ break;
+ }
+ }
for (TUActions::iterator I = TranslationUnitActions.begin(),
E = TranslationUnitActions.end(); I != E; ++I) {
(*I)(*this, *Mgr, *TU);
}
- if (!ObjCImplementationActions.empty()) {
- for (DeclContext::decl_iterator I = TU->decls_begin(),
- E = TU->decls_end();
- I != E; ++I)
- if (ObjCImplementationDecl* ID = dyn_cast<ObjCImplementationDecl>(*I))
- HandleCode(ID, 0, ObjCImplementationActions);
- }
-
// Explicitly destroy the PathDiagnosticClient. This will flush its output.
// FIXME: This should be replaced with something that doesn't rely on
// side-effects in PathDiagnosticClient's destructor. This is required when
@@ -278,7 +272,8 @@ static void FindBlocks(DeclContext *D, llvm::SmallVectorImpl<Decl*> &WL) {
void AnalysisConsumer::HandleCode(Decl *D, Stmt* Body, Actions& actions) {
// Don't run the actions if an error has occured with parsing the file.
- if (PP.getDiagnostics().hasErrorOccurred())
+ Diagnostic &Diags = PP.getDiagnostics();
+ if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred())
return;
// Don't run the actions on declarations in header files unless
@@ -310,7 +305,6 @@ void AnalysisConsumer::HandleCode(Decl *D, Stmt* Body, Actions& actions) {
static void ActionWarnDeadStores(AnalysisConsumer &C, AnalysisManager& mgr,
Decl *D) {
if (LiveVariables *L = mgr.getLiveVariables(D)) {
- C.DisplayFunction(D);
BugReporter BR(mgr);
CheckDeadStores(*mgr.getCFG(D), *L, mgr.getParentMap(D), BR);
}
@@ -319,7 +313,6 @@ static void ActionWarnDeadStores(AnalysisConsumer &C, AnalysisManager& mgr,
static void ActionWarnUninitVals(AnalysisConsumer &C, AnalysisManager& mgr,
Decl *D) {
if (CFG* c = mgr.getCFG(D)) {
- C.DisplayFunction(D);
CheckUninitializedValues(*c, mgr.getASTContext(), mgr.getDiagnostic());
}
}
@@ -331,15 +324,11 @@ static void ActionGRExprEngine(AnalysisConsumer &C, AnalysisManager& mgr,
llvm::OwningPtr<GRTransferFuncs> TF(tf);
- // Display progress.
- C.DisplayFunction(D);
-
// Construct the analysis engine. We first query for the LiveVariables
// information to see if the CFG is valid.
// FIXME: Inter-procedural analysis will need to handle invalid CFGs.
if (!mgr.getLiveVariables(D))
return;
-
GRExprEngine Eng(mgr, TF.take());
if (C.Opts.EnableExperimentalInternalChecks)
@@ -358,7 +347,7 @@ static void ActionGRExprEngine(AnalysisConsumer &C, AnalysisManager& mgr,
}
// Execute the worklist algorithm.
- Eng.ExecuteWorkList(mgr.getStackFrame(D));
+ Eng.ExecuteWorkList(mgr.getStackFrame(D), mgr.getMaxNodes());
// Release the auditor (if any) so that it doesn't monitor the graph
// created BugReporter.
@@ -406,28 +395,24 @@ static void ActionObjCMemChecker(AnalysisConsumer &C, AnalysisManager& mgr,
static void ActionDisplayLiveVariables(AnalysisConsumer &C,
AnalysisManager& mgr, Decl *D) {
if (LiveVariables* L = mgr.getLiveVariables(D)) {
- C.DisplayFunction(D);
L->dumpBlockLiveness(mgr.getSourceManager());
}
}
static void ActionCFGDump(AnalysisConsumer &C, AnalysisManager& mgr, Decl *D) {
if (CFG *cfg = mgr.getCFG(D)) {
- C.DisplayFunction(D);
cfg->dump(mgr.getLangOptions());
}
}
static void ActionCFGView(AnalysisConsumer &C, AnalysisManager& mgr, Decl *D) {
if (CFG *cfg = mgr.getCFG(D)) {
- C.DisplayFunction(D);
cfg->viewCFG(mgr.getLangOptions());
}
}
static void ActionSecuritySyntacticChecks(AnalysisConsumer &C,
AnalysisManager &mgr, Decl *D) {
- C.DisplayFunction(D);
BugReporter BR(mgr);
CheckSecuritySyntaxOnly(D, BR);
}
@@ -443,86 +428,28 @@ static void ActionWarnObjCDealloc(AnalysisConsumer &C, AnalysisManager& mgr,
Decl *D) {
if (mgr.getLangOptions().getGCMode() == LangOptions::GCOnly)
return;
-
- C.DisplayFunction(D);
BugReporter BR(mgr);
CheckObjCDealloc(cast<ObjCImplementationDecl>(D), mgr.getLangOptions(), BR);
}
static void ActionWarnObjCUnusedIvars(AnalysisConsumer &C, AnalysisManager& mgr,
Decl *D) {
- C.DisplayFunction(D);
BugReporter BR(mgr);
CheckObjCUnusedIvar(cast<ObjCImplementationDecl>(D), BR);
}
static void ActionWarnObjCMethSigs(AnalysisConsumer &C, AnalysisManager& mgr,
Decl *D) {
- C.DisplayFunction(D);
BugReporter BR(mgr);
CheckObjCInstMethSignature(cast<ObjCImplementationDecl>(D), BR);
}
static void ActionWarnSizeofPointer(AnalysisConsumer &C, AnalysisManager &mgr,
Decl *D) {
- C.DisplayFunction(D);
BugReporter BR(mgr);
CheckSizeofPointer(D, BR);
}
-static void ActionInlineCall(AnalysisConsumer &C, AnalysisManager &mgr,
- 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);
-
- // FIXME: Make a fake transfer function. The GRTransferFunc interface
- // eventually will be removed.
- GRExprEngine Eng(mgr, new GRTransferFuncs());
-
- if (C.Opts.EnableExperimentalInternalChecks)
- RegisterExperimentalInternalChecks(Eng);
-
- RegisterAppleChecks(Eng, *D);
-
- if (C.Opts.EnableExperimentalChecks)
- RegisterExperimentalChecks(Eng);
-
- // Register call inliner as the last checker.
- RegisterCallInliner(Eng);
-
- // Execute the worklist algorithm.
- Eng.ExecuteWorkList(mgr.getStackFrame(D));
-
- // Visualize the exploded graph.
- if (mgr.shouldVisualizeGraphviz())
- Eng.ViewGraph(mgr.shouldTrimGraph());
-
- // Display warnings.
- Eng.getBugReporter().FlushReports();
-}
-
//===----------------------------------------------------------------------===//
// AnalysisConsumer creation.
//===----------------------------------------------------------------------===//
diff --git a/lib/Frontend/CacheTokens.cpp b/lib/Frontend/CacheTokens.cpp
index d069e8f42f26..a5fcebe99411 100644
--- a/lib/Frontend/CacheTokens.cpp
+++ b/lib/Frontend/CacheTokens.cpp
@@ -475,7 +475,7 @@ void PTHWriter::GeneratePTH(const std::string &MainFile) {
if (!P.isAbsolute())
continue;
- const llvm::MemoryBuffer *B = C.getBuffer(PP.getDiagnostics());
+ const llvm::MemoryBuffer *B = C.getBuffer(PP.getDiagnostics(), SM);
if (!B) continue;
FileID FID = SM.createFileID(FE, SourceLocation(), SrcMgr::C_User);
@@ -550,8 +550,7 @@ void clang::CacheTokens(Preprocessor &PP, llvm::raw_fd_ostream* OS) {
// Lex through the entire file. This will populate SourceManager with
// all of the header information.
Token Tok;
- if (PP.EnterMainSourceFile())
- return;
+ PP.EnterMainSourceFile();
do { PP.Lex(Tok); } while (Tok.isNot(tok::eof));
// Generate the PTH file.
diff --git a/lib/Frontend/CodeGenAction.cpp b/lib/Frontend/CodeGenAction.cpp
index b1795a3aa3b5..79d7d5f4c241 100644
--- a/lib/Frontend/CodeGenAction.cpp
+++ b/lib/Frontend/CodeGenAction.cpp
@@ -8,16 +8,18 @@
//===----------------------------------------------------------------------===//
#include "clang/Frontend/CodeGenAction.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/TargetOptions.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclGroup.h"
-#include "clang/Basic/TargetInfo.h"
-#include "clang/Basic/TargetOptions.h"
#include "clang/CodeGen/CodeGenOptions.h"
#include "clang/CodeGen/ModuleBuilder.h"
#include "clang/Frontend/ASTConsumers.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendDiagnostic.h"
+#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/ADT/OwningPtr.h"
@@ -28,6 +30,8 @@
#include "llvm/CodeGen/RegAllocRegistry.h"
#include "llvm/CodeGen/SchedulerRegistry.h"
#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/StandardPasses.h"
#include "llvm/Support/Timer.h"
#include "llvm/Target/SubtargetFeature.h"
@@ -87,7 +91,7 @@ namespace {
const LangOptions &langopts, const CodeGenOptions &compopts,
const TargetOptions &targetopts, bool TimePasses,
const std::string &infile, llvm::raw_ostream *OS,
- LLVMContext& C) :
+ LLVMContext &C) :
Diags(_Diags),
Action(action),
CodeGenOpts(compopts),
@@ -175,6 +179,15 @@ namespace {
virtual void CompleteTentativeDefinition(VarDecl *D) {
Gen->CompleteTentativeDefinition(D);
}
+
+ static void InlineAsmDiagHandler(const llvm::SMDiagnostic &SM,void *Context,
+ unsigned LocCookie) {
+ SourceLocation Loc = SourceLocation::getFromRawEncoding(LocCookie);
+ ((BackendConsumer*)Context)->InlineAsmDiagHandler2(SM, Loc);
+ }
+
+ void InlineAsmDiagHandler2(const llvm::SMDiagnostic &,
+ SourceLocation LocCookie);
};
}
@@ -211,127 +224,122 @@ bool BackendConsumer::AddEmitPasses() {
if (Action == Backend_EmitBC) {
getPerModulePasses()->add(createBitcodeWriterPass(FormattedOutStream));
- } else if (Action == Backend_EmitLL) {
+ return true;
+ }
+
+ if (Action == Backend_EmitLL) {
getPerModulePasses()->add(createPrintModulePass(&FormattedOutStream));
+ return true;
+ }
+
+ bool Fast = CodeGenOpts.OptimizationLevel == 0;
+
+ // Create the TargetMachine for generating code.
+ std::string Error;
+ std::string Triple = TheModule->getTargetTriple();
+ const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
+ if (!TheTarget) {
+ Diags.Report(diag::err_fe_unable_to_create_target) << Error;
+ return false;
+ }
+
+ // FIXME: Expose these capabilities via actual APIs!!!! Aside from just
+ // being gross, this is also totally broken if we ever care about
+ // concurrency.
+ llvm::NoFramePointerElim = CodeGenOpts.DisableFPElim;
+ if (CodeGenOpts.FloatABI == "soft")
+ llvm::FloatABIType = llvm::FloatABI::Soft;
+ else if (CodeGenOpts.FloatABI == "hard")
+ llvm::FloatABIType = llvm::FloatABI::Hard;
+ else {
+ assert(CodeGenOpts.FloatABI.empty() && "Invalid float abi!");
+ llvm::FloatABIType = llvm::FloatABI::Default;
+ }
+ NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS;
+ llvm::UseSoftFloat = CodeGenOpts.SoftFloat;
+ UnwindTablesMandatory = CodeGenOpts.UnwindTables;
+
+ TargetMachine::setAsmVerbosityDefault(CodeGenOpts.AsmVerbose);
+
+ TargetMachine::setFunctionSections(CodeGenOpts.FunctionSections);
+ TargetMachine::setDataSections (CodeGenOpts.DataSections);
+
+ // FIXME: Parse this earlier.
+ if (CodeGenOpts.RelocationModel == "static") {
+ TargetMachine::setRelocationModel(llvm::Reloc::Static);
+ } else if (CodeGenOpts.RelocationModel == "pic") {
+ TargetMachine::setRelocationModel(llvm::Reloc::PIC_);
} else {
- bool Fast = CodeGenOpts.OptimizationLevel == 0;
-
- // Create the TargetMachine for generating code.
- std::string Error;
- std::string Triple = TheModule->getTargetTriple();
- const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
- if (!TheTarget) {
- Diags.Report(diag::err_fe_unable_to_create_target) << Error;
- return false;
- }
+ assert(CodeGenOpts.RelocationModel == "dynamic-no-pic" &&
+ "Invalid PIC model!");
+ TargetMachine::setRelocationModel(llvm::Reloc::DynamicNoPIC);
+ }
+ // FIXME: Parse this earlier.
+ if (CodeGenOpts.CodeModel == "small") {
+ TargetMachine::setCodeModel(llvm::CodeModel::Small);
+ } else if (CodeGenOpts.CodeModel == "kernel") {
+ TargetMachine::setCodeModel(llvm::CodeModel::Kernel);
+ } else if (CodeGenOpts.CodeModel == "medium") {
+ TargetMachine::setCodeModel(llvm::CodeModel::Medium);
+ } else if (CodeGenOpts.CodeModel == "large") {
+ TargetMachine::setCodeModel(llvm::CodeModel::Large);
+ } else {
+ assert(CodeGenOpts.CodeModel.empty() && "Invalid code model!");
+ TargetMachine::setCodeModel(llvm::CodeModel::Default);
+ }
- // FIXME: Expose these capabilities via actual APIs!!!! Aside from just
- // being gross, this is also totally broken if we ever care about
- // concurrency.
- llvm::NoFramePointerElim = CodeGenOpts.DisableFPElim;
- if (CodeGenOpts.FloatABI == "soft")
- llvm::FloatABIType = llvm::FloatABI::Soft;
- else if (CodeGenOpts.FloatABI == "hard")
- llvm::FloatABIType = llvm::FloatABI::Hard;
- else {
- assert(CodeGenOpts.FloatABI.empty() && "Invalid float abi!");
- llvm::FloatABIType = llvm::FloatABI::Default;
- }
- NoZerosInBSS = CodeGenOpts.NoZeroInitializedInBSS;
- llvm::UseSoftFloat = CodeGenOpts.SoftFloat;
- UnwindTablesMandatory = CodeGenOpts.UnwindTables;
-
- TargetMachine::setAsmVerbosityDefault(CodeGenOpts.AsmVerbose);
-
- // FIXME: Parse this earlier.
- if (CodeGenOpts.RelocationModel == "static") {
- TargetMachine::setRelocationModel(llvm::Reloc::Static);
- } else if (CodeGenOpts.RelocationModel == "pic") {
- TargetMachine::setRelocationModel(llvm::Reloc::PIC_);
- } else {
- assert(CodeGenOpts.RelocationModel == "dynamic-no-pic" &&
- "Invalid PIC model!");
- TargetMachine::setRelocationModel(llvm::Reloc::DynamicNoPIC);
- }
- // FIXME: Parse this earlier.
- if (CodeGenOpts.CodeModel == "small") {
- TargetMachine::setCodeModel(llvm::CodeModel::Small);
- } else if (CodeGenOpts.CodeModel == "kernel") {
- TargetMachine::setCodeModel(llvm::CodeModel::Kernel);
- } else if (CodeGenOpts.CodeModel == "medium") {
- TargetMachine::setCodeModel(llvm::CodeModel::Medium);
- } else if (CodeGenOpts.CodeModel == "large") {
- TargetMachine::setCodeModel(llvm::CodeModel::Large);
- } else {
- assert(CodeGenOpts.CodeModel.empty() && "Invalid code model!");
- TargetMachine::setCodeModel(llvm::CodeModel::Default);
- }
+ std::vector<const char *> BackendArgs;
+ BackendArgs.push_back("clang"); // Fake program name.
+ if (!CodeGenOpts.DebugPass.empty()) {
+ BackendArgs.push_back("-debug-pass");
+ BackendArgs.push_back(CodeGenOpts.DebugPass.c_str());
+ }
+ if (!CodeGenOpts.LimitFloatPrecision.empty()) {
+ BackendArgs.push_back("-limit-float-precision");
+ BackendArgs.push_back(CodeGenOpts.LimitFloatPrecision.c_str());
+ }
+ if (llvm::TimePassesIsEnabled)
+ BackendArgs.push_back("-time-passes");
+ BackendArgs.push_back(0);
+ llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1,
+ const_cast<char **>(&BackendArgs[0]));
+
+ std::string FeaturesStr;
+ if (TargetOpts.CPU.size() || TargetOpts.Features.size()) {
+ SubtargetFeatures Features;
+ Features.setCPU(TargetOpts.CPU);
+ for (std::vector<std::string>::const_iterator
+ it = TargetOpts.Features.begin(),
+ ie = TargetOpts.Features.end(); it != ie; ++it)
+ Features.AddFeature(*it);
+ FeaturesStr = Features.getString();
+ }
+ TargetMachine *TM = TheTarget->createTargetMachine(Triple, FeaturesStr);
- std::vector<const char *> BackendArgs;
- BackendArgs.push_back("clang"); // Fake program name.
- if (!CodeGenOpts.DebugPass.empty()) {
- BackendArgs.push_back("-debug-pass");
- BackendArgs.push_back(CodeGenOpts.DebugPass.c_str());
- }
- if (!CodeGenOpts.LimitFloatPrecision.empty()) {
- BackendArgs.push_back("-limit-float-precision");
- BackendArgs.push_back(CodeGenOpts.LimitFloatPrecision.c_str());
- }
- if (llvm::TimePassesIsEnabled)
- BackendArgs.push_back("-time-passes");
- BackendArgs.push_back(0);
- llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1,
- (char**) &BackendArgs[0]);
-
- std::string FeaturesStr;
- if (TargetOpts.CPU.size() || TargetOpts.Features.size()) {
- SubtargetFeatures Features;
- Features.setCPU(TargetOpts.CPU);
- for (std::vector<std::string>::const_iterator
- it = TargetOpts.Features.begin(),
- ie = TargetOpts.Features.end(); it != ie; ++it)
- Features.AddFeature(*it);
- FeaturesStr = Features.getString();
- }
- TargetMachine *TM = TheTarget->createTargetMachine(Triple, FeaturesStr);
-
- // Set register scheduler & allocation policy.
- RegisterScheduler::setDefault(createDefaultScheduler);
- RegisterRegAlloc::setDefault(Fast ? createLocalRegisterAllocator :
- createLinearScanRegisterAllocator);
-
- // From llvm-gcc:
- // If there are passes we have to run on the entire module, we do codegen
- // as a separate "pass" after that happens.
- // FIXME: This is disabled right now until bugs can be worked out. Reenable
- // this for fast -O0 compiles!
- FunctionPassManager *PM = getCodeGenPasses();
- CodeGenOpt::Level OptLevel = CodeGenOpt::Default;
-
- switch (CodeGenOpts.OptimizationLevel) {
- default: break;
- case 0: OptLevel = CodeGenOpt::None; break;
- case 3: OptLevel = CodeGenOpt::Aggressive; break;
- }
+ // Set register scheduler & allocation policy.
+ RegisterScheduler::setDefault(createDefaultScheduler);
+ RegisterRegAlloc::setDefault(Fast ? createLocalRegisterAllocator :
+ createLinearScanRegisterAllocator);
- // Request that addPassesToEmitFile run the Verifier after running
- // passes which modify the IR.
-#ifndef NDEBUG
- bool DisableVerify = false;
-#else
- bool DisableVerify = true;
-#endif
-
- // Normal mode, emit a .s or .o file by running the code generator. Note,
- // this also adds codegenerator level optimization passes.
- TargetMachine::CodeGenFileType CGFT = TargetMachine::CGFT_AssemblyFile;
- if (Action == Backend_EmitObj)
- CGFT = TargetMachine::CGFT_ObjectFile;
- if (TM->addPassesToEmitFile(*PM, FormattedOutStream, CGFT, OptLevel,
- DisableVerify)) {
- Diags.Report(diag::err_fe_unable_to_interface_with_target);
- return false;
- }
+ // Create the code generator passes.
+ FunctionPassManager *PM = getCodeGenPasses();
+ CodeGenOpt::Level OptLevel = CodeGenOpt::Default;
+
+ switch (CodeGenOpts.OptimizationLevel) {
+ default: break;
+ case 0: OptLevel = CodeGenOpt::None; break;
+ case 3: OptLevel = CodeGenOpt::Aggressive; break;
+ }
+
+ // 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,
+ /*DisableVerify=*/!CodeGenOpts.VerifyModule)) {
+ Diags.Report(diag::err_fe_unable_to_interface_with_target);
+ return false;
}
return true;
@@ -432,14 +440,81 @@ void BackendConsumer::EmitAssembly() {
if (CodeGenPasses) {
PrettyStackTraceString CrashInfo("Code generation");
+
+ // Install an inline asm handler so that diagnostics get printed through our
+ // diagnostics hooks.
+ LLVMContext &Ctx = TheModule->getContext();
+ void *OldHandler = Ctx.getInlineAsmDiagnosticHandler();
+ void *OldContext = Ctx.getInlineAsmDiagnosticContext();
+ Ctx.setInlineAsmDiagnosticHandler((void*)(intptr_t)InlineAsmDiagHandler,
+ this);
+
CodeGenPasses->doInitialization();
for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
if (!I->isDeclaration())
CodeGenPasses->run(*I);
CodeGenPasses->doFinalization();
+
+ Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext);
}
}
+/// ConvertBackendLocation - Convert a location in a temporary llvm::SourceMgr
+/// buffer to be a valid FullSourceLoc.
+static FullSourceLoc ConvertBackendLocation(const llvm::SMDiagnostic &D,
+ SourceManager &CSM) {
+ // Get both the clang and llvm source managers. The location is relative to
+ // a memory buffer that the LLVM Source Manager is handling, we need to add
+ // a copy to the Clang source manager.
+ const llvm::SourceMgr &LSM = *D.getSourceMgr();
+
+ // We need to copy the underlying LLVM memory buffer because llvm::SourceMgr
+ // already owns its one and clang::SourceManager wants to own its one.
+ const MemoryBuffer *LBuf =
+ LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
+
+ // Create the copy and transfer ownership to clang::SourceManager.
+ llvm::MemoryBuffer *CBuf =
+ llvm::MemoryBuffer::getMemBufferCopy(LBuf->getBuffer(),
+ LBuf->getBufferIdentifier());
+ FileID FID = CSM.createFileIDForMemBuffer(CBuf);
+
+ // Translate the offset into the file.
+ unsigned Offset = D.getLoc().getPointer() - LBuf->getBufferStart();
+ SourceLocation NewLoc =
+ CSM.getLocForStartOfFile(FID).getFileLocWithOffset(Offset);
+ return FullSourceLoc(NewLoc, CSM);
+}
+
+
+/// InlineAsmDiagHandler2 - This function is invoked when the backend hits an
+/// error parsing inline asm. The SMDiagnostic indicates the error relative to
+/// the temporary memory buffer that the inline asm parser has set up.
+void BackendConsumer::InlineAsmDiagHandler2(const llvm::SMDiagnostic &D,
+ SourceLocation LocCookie) {
+ // There are a couple of different kinds of errors we could get here. First,
+ // we re-format the SMDiagnostic in terms of a clang diagnostic.
+
+ // Strip "error: " off the start of the message string.
+ llvm::StringRef Message = D.getMessage();
+ if (Message.startswith("error: "))
+ Message = Message.substr(7);
+
+ // There are two cases: the SMDiagnostic could have a inline asm source
+ // location or it might not. If it does, translate the location.
+ FullSourceLoc Loc;
+ if (D.getLoc() != SMLoc())
+ Loc = ConvertBackendLocation(D, Context->getSourceManager());
+ Diags.Report(Loc, diag::err_fe_inline_asm).AddString(Message);
+
+ // This could be a problem with no clang-level source location information.
+ // In this case, LocCookie is invalid. If there is source level information,
+ // print an "generated from" note.
+ if (LocCookie.isValid())
+ Diags.Report(FullSourceLoc(LocCookie, Context->getSourceManager()),
+ diag::note_fe_inline_asm_here);
+}
+
//
CodeGenAction::CodeGenAction(unsigned _Act) : Act(_Act) {}
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index 1f915e3713d3..5ed9c409a3dc 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -513,11 +513,20 @@ bool CompilerInstance::ExecuteAction(FrontendAction &Act) {
}
}
- if (getDiagnosticOpts().ShowCarets)
- if (unsigned NumDiagnostics = getDiagnostics().getNumDiagnostics())
- OS << NumDiagnostics << " diagnostic"
- << (NumDiagnostics == 1 ? "" : "s")
- << " generated.\n";
+ if (getDiagnosticOpts().ShowCarets) {
+ unsigned NumWarnings = getDiagnostics().getNumWarnings();
+ unsigned NumErrors = getDiagnostics().getNumErrors() -
+ getDiagnostics().getNumErrorsSuppressed();
+
+ if (NumWarnings)
+ OS << NumWarnings << " warning" << (NumWarnings == 1 ? "" : "s");
+ if (NumWarnings && NumErrors)
+ OS << " and ";
+ if (NumErrors)
+ OS << NumErrors << " error" << (NumErrors == 1 ? "" : "s");
+ if (NumWarnings || NumErrors)
+ OS << " generated.\n";
+ }
if (getFrontendOpts().ShowStats) {
getFileManager().PrintStats();
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index dc2c6bf3614a..8ffdde2aa9b5 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -145,9 +145,12 @@ static void CodeGenOptsToArgs(const CodeGenOptions &Opts,
// TimePasses is only derived.
// UnitAtATime is unused.
// UnrollLoops is only derived.
- // VerifyModule is only derived.
// Inlining is only derived.
+ if (Opts.DataSections)
+ Res.push_back("-fdata-sections");
+ if (Opts.FunctionSections)
+ Res.push_back("-ffunction-sections");
if (Opts.AsmVerbose)
Res.push_back("-masm-verbose");
if (!Opts.CodeModel.empty()) {
@@ -174,8 +177,16 @@ 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");
+ switch (Opts.getObjCDispatchMethod()) {
+ case CodeGenOptions::Legacy:
+ break;
+ case CodeGenOptions::Mixed:
+ Res.push_back("-fobjc-dispatch-method=mixed");
+ break;
+ case CodeGenOptions::NonLegacy:
+ Res.push_back("-fobjc-dispatch-method=non-legacy");
+ break;
+ }
if (Opts.SoftFloat)
Res.push_back("-msoft-float");
if (Opts.UnwindTables)
@@ -232,6 +243,15 @@ static void DiagnosticOptsToArgs(const DiagnosticOptions &Opts,
Res.push_back("-fdiagnostics-binary");
if (Opts.ShowOptionNames)
Res.push_back("-fdiagnostics-show-option");
+ if (Opts.ErrorLimit) {
+ Res.push_back("-ferror-limit");
+ Res.push_back(llvm::utostr(Opts.ErrorLimit));
+ }
+ if (Opts.TemplateBacktraceLimit != 10) {
+ Res.push_back("-ftemplate-backtrace-limit");
+ Res.push_back(llvm::utostr(Opts.TemplateBacktraceLimit));
+ }
+
if (Opts.TabStop != DiagnosticOptions::DefaultTabStop) {
Res.push_back("-ftabstop");
Res.push_back(llvm::utostr(Opts.TabStop));
@@ -279,7 +299,6 @@ static const char *getActionName(frontend::ActionKind Kind) {
case frontend::ASTPrintXML: return "-ast-print-xml";
case frontend::ASTView: return "-ast-view";
case frontend::DumpRawTokens: return "-dump-raw-tokens";
- case frontend::DumpRecordLayouts: return "-dump-record-layouts";
case frontend::DumpTokens: return "-dump-tokens";
case frontend::EmitAssembly: return "-S";
case frontend::EmitBC: return "-emit-llvm-bc";
@@ -349,12 +368,6 @@ static void FrontendOptsToArgs(const FrontendOptions &Opts,
Res.push_back("-cxx-inheritance-view");
Res.push_back(Opts.ViewClassInheritance);
}
- for (unsigned i = 0, e = Opts.FixItLocations.size(); i != e; ++i) {
- Res.push_back("-fixit-at");
- Res.push_back(Opts.FixItLocations[i].FileName + ":" +
- llvm::utostr(Opts.FixItLocations[i].Line) + ":" +
- llvm::utostr(Opts.FixItLocations[i].Column));
- }
if (!Opts.CodeCompletionAt.FileName.empty()) {
Res.push_back("-code-completion-at");
Res.push_back(Opts.CodeCompletionAt.FileName + ":" +
@@ -376,6 +389,10 @@ static void FrontendOptsToArgs(const FrontendOptions &Opts,
Res.push_back("-ast-merge");
Res.push_back(Opts.ASTMergeFiles[i]);
}
+ for (unsigned i = 0, e = Opts.LLVMArgs.size(); i != e; ++i) {
+ Res.push_back("-mllvm");
+ Res.push_back(Opts.LLVMArgs[i]);
+ }
}
static void HeaderSearchOptsToArgs(const HeaderSearchOptions &Opts,
@@ -389,7 +406,7 @@ static void HeaderSearchOptsToArgs(const HeaderSearchOptions &Opts,
for (unsigned i = 0, e = Opts.UserEntries.size(); i != e; ++i) {
const HeaderSearchOptions::Entry &E = Opts.UserEntries[i];
if (E.IsFramework && (E.Group != frontend::Angled || !E.IsUserSupplied))
- llvm::llvm_report_error("Invalid option set!");
+ llvm::report_fatal_error("Invalid option set!");
if (E.IsUserSupplied) {
if (E.Group == frontend::After) {
Res.push_back("-idirafter");
@@ -403,7 +420,7 @@ static void HeaderSearchOptsToArgs(const HeaderSearchOptions &Opts,
}
} else {
if (E.Group != frontend::Angled && E.Group != frontend::System)
- llvm::llvm_report_error("Invalid option set!");
+ llvm::report_fatal_error("Invalid option set!");
Res.push_back(E.Group == frontend::Angled ? "-iwithprefixbefore" :
"-iwithprefix");
}
@@ -412,23 +429,23 @@ static void HeaderSearchOptsToArgs(const HeaderSearchOptions &Opts,
if (!Opts.EnvIncPath.empty()) {
// FIXME: Provide an option for this, and move env detection to driver.
- llvm::llvm_report_error("Not yet implemented!");
+ llvm::report_fatal_error("Not yet implemented!");
}
if (!Opts.CEnvIncPath.empty()) {
// FIXME: Provide an option for this, and move env detection to driver.
- llvm::llvm_report_error("Not yet implemented!");
+ llvm::report_fatal_error("Not yet implemented!");
}
if (!Opts.ObjCEnvIncPath.empty()) {
// FIXME: Provide an option for this, and move env detection to driver.
- llvm::llvm_report_error("Not yet implemented!");
+ llvm::report_fatal_error("Not yet implemented!");
}
if (!Opts.CXXEnvIncPath.empty()) {
// FIXME: Provide an option for this, and move env detection to driver.
- llvm::llvm_report_error("Not yet implemented!");
+ llvm::report_fatal_error("Not yet implemented!");
}
if (!Opts.ObjCXXEnvIncPath.empty()) {
// FIXME: Provide an option for this, and move env detection to driver.
- llvm::llvm_report_error("Not yet implemented!");
+ llvm::report_fatal_error("Not yet implemented!");
}
if (!Opts.ResourceDir.empty()) {
Res.push_back("-resource-dir");
@@ -462,6 +479,10 @@ static void LangOptsToArgs(const LangOptions &Opts,
// BCPLComment, C99, CPlusPlus0x, Digraphs, GNUInline, ImplicitInt, GNUMode
if (Opts.DollarIdents)
Res.push_back("-fdollars-in-identifiers");
+ if (Opts.GNUMode && !Opts.GNUKeywords)
+ Res.push_back("-fno-gnu-keywords");
+ if (!Opts.GNUMode && Opts.GNUKeywords)
+ Res.push_back("-fgnu-keywords");
if (Opts.Microsoft)
Res.push_back("-fms-extensions");
if (Opts.ObjCNonFragileABI)
@@ -515,15 +536,24 @@ static void LangOptsToArgs(const LangOptions &Opts,
// OptimizeSize is implicit.
if (Opts.Static)
Res.push_back("-static-define");
+ if (Opts.DumpRecordLayouts)
+ Res.push_back("-fdump-record-layouts");
+ if (Opts.DumpVTableLayouts)
+ Res.push_back("-fdump-vtable-layouts");
+ if (Opts.NoBitFieldTypeAlign)
+ Res.push_back("-fno-bitfield-type-alignment");
+ if (Opts.SjLjExceptions)
+ Res.push_back("-fsjlj-exceptions");
if (Opts.PICLevel) {
Res.push_back("-pic-level");
Res.push_back(llvm::utostr(Opts.PICLevel));
}
if (Opts.ObjCGCBitmapPrint)
Res.push_back("-print-ivar-layout");
- // FIXME: Don't forget to update when the default changes!
- if (Opts.AccessControl)
- Res.push_back("-faccess-control");
+ if (Opts.NoConstantCFStrings)
+ Res.push_back("-fno-constant-cfstrings");
+ if (!Opts.AccessControl)
+ Res.push_back("-fno-access-control");
if (!Opts.CharIsSigned)
Res.push_back("-fno-signed-char");
if (Opts.ShortWChar)
@@ -606,7 +636,7 @@ static void PreprocessorOptsToArgs(const PreprocessorOptions &Opts,
static void PreprocessorOutputOptsToArgs(const PreprocessorOutputOptions &Opts,
std::vector<std::string> &Res) {
if (!Opts.ShowCPP && !Opts.ShowMacros)
- llvm::llvm_report_error("Invalid option combination!");
+ llvm::report_fatal_error("Invalid option combination!");
if (Opts.ShowCPP && Opts.ShowMacros)
Res.push_back("-dD");
@@ -756,6 +786,7 @@ static void ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
Opts.EnableExperimentalInternalChecks =
Args.hasArg(OPT_analyzer_experimental_internal_checks);
Opts.TrimGraph = Args.hasArg(OPT_trim_egraph);
+ Opts.MaxNodes = getLastArgIntValue(Args, OPT_analyzer_max_nodes,150000,Diags);
}
static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
@@ -796,13 +827,28 @@ 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.FunctionSections = Args.hasArg(OPT_ffunction_sections);
+ Opts.DataSections = Args.hasArg(OPT_fdata_sections);
+
Opts.MainFileName = getLastArgValue(Args, OPT_main_file_name);
Opts.VerifyModule = !Args.hasArg(OPT_disable_llvm_verifier);
+
+ if (Arg *A = Args.getLastArg(OPT_fobjc_dispatch_method_EQ)) {
+ llvm::StringRef Name = A->getValue(Args);
+ unsigned Method = llvm::StringSwitch<unsigned>(Name)
+ .Case("legacy", CodeGenOptions::Legacy)
+ .Case("non-legacy", CodeGenOptions::NonLegacy)
+ .Case("mixed", CodeGenOptions::Mixed)
+ .Default(~0U);
+ if (Method == ~0U)
+ Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
+ else
+ Opts.ObjCDispatchMethod = Method;
+ }
}
static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
@@ -830,6 +876,9 @@ static void ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
Opts.ShowSourceRanges = Args.hasArg(OPT_fdiagnostics_print_source_range_info);
Opts.VerifyDiagnostics = Args.hasArg(OPT_verify);
Opts.BinaryOutput = Args.hasArg(OPT_fdiagnostics_binary);
+ Opts.ErrorLimit = getLastArgIntValue(Args, OPT_ferror_limit, 0, Diags);
+ Opts.TemplateBacktraceLimit
+ = getLastArgIntValue(Args, OPT_ftemplate_backtrace_limit, 0, Diags);
Opts.TabStop = getLastArgIntValue(Args, OPT_ftabstop,
DiagnosticOptions::DefaultTabStop, Diags);
if (Opts.TabStop == 0 || Opts.TabStop > DiagnosticOptions::MaxTabStop) {
@@ -860,8 +909,6 @@ ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Diagnostic &Diags) {
Opts.ProgramAction = frontend::ASTView; break;
case OPT_dump_raw_tokens:
Opts.ProgramAction = frontend::DumpRawTokens; break;
- case OPT_dump_record_layouts:
- Opts.ProgramAction = frontend::DumpRecordLayouts; break;
case OPT_dump_tokens:
Opts.ProgramAction = frontend::DumpTokens; break;
case OPT_S:
@@ -876,6 +923,9 @@ ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Diagnostic &Diags) {
Opts.ProgramAction = frontend::EmitLLVMOnly; break;
case OPT_emit_obj:
Opts.ProgramAction = frontend::EmitObj; break;
+ case OPT_fixit_EQ:
+ Opts.FixItSuffix = A->getValue(Args);
+ // fall-through!
case OPT_fixit:
Opts.ProgramAction = frontend::FixIt; break;
case OPT_emit_pch:
@@ -922,20 +972,6 @@ ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Diagnostic &Diags) {
!Args.hasArg(OPT_no_code_completion_debug_printer);
Opts.DisableFree = Args.hasArg(OPT_disable_free);
- Opts.FixItLocations.clear();
- for (arg_iterator it = Args.filtered_begin(OPT_fixit_at),
- ie = Args.filtered_end(); it != ie; ++it) {
- const char *Loc = it->getValue(Args);
- ParsedSourceLocation PSL = ParsedSourceLocation::FromString(Loc);
-
- if (PSL.FileName.empty()) {
- Diags.Report(diag::err_drv_invalid_value) << it->getAsString(Args) << Loc;
- continue;
- }
-
- Opts.FixItLocations.push_back(PSL);
- }
-
Opts.OutputFile = getLastArgValue(Args, OPT_o);
Opts.Plugins = getAllArgValues(Args, OPT_load);
Opts.RelocatablePCH = Args.hasArg(OPT_relocatable_pch);
@@ -946,6 +982,7 @@ ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, Diagnostic &Diags) {
Opts.ShowVersion = Args.hasArg(OPT_version);
Opts.ViewClassInheritance = getLastArgValue(Args, OPT_cxx_inheritance_view);
Opts.ASTMergeFiles = getAllArgValues(Args, OPT_ast_merge);
+ Opts.LLVMArgs = getAllArgValues(Args, OPT_mllvm);
FrontendOptions::InputKind DashX = FrontendOptions::IK_None;
if (const Arg *A = Args.getLastArg(OPT_x)) {
@@ -1129,6 +1166,14 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args,
// OpenCL and C++ both have bool, true, false keywords.
Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
+ // We abuse '-f[no-]gnu-keywords' to force overriding all GNU-extension
+ // keywords. This behavior is provided by GCC's poorly named '-fasm' flag,
+ // while a subset (the non-C++ GNU keywords) is provided by GCC's
+ // '-fgnu-keywords'. Clang conflates the two for simplicity under the single
+ // name, as it doesn't seem a useful distinction.
+ Opts.GNUKeywords = Args.hasFlag(OPT_fgnu_keywords, OPT_fno_gnu_keywords,
+ Opts.GNUMode);
+
if (Opts.CPlusPlus)
Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names);
@@ -1139,6 +1184,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args,
if (Args.hasArg(OPT_print_ivar_layout))
Opts.ObjCGCBitmapPrint = 1;
+ if (Args.hasArg(OPT_fno_constant_cfstrings))
+ Opts.NoConstantCFStrings = 1;
if (Args.hasArg(OPT_faltivec))
Opts.AltiVec = 1;
@@ -1186,10 +1233,10 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
Opts.AssumeSaneOperatorNew = !Args.hasArg(OPT_fno_assume_sane_operator_new);
Opts.HeinousExtensions = Args.hasArg(OPT_fheinous_gnu_extensions);
- Opts.AccessControl = Args.hasArg(OPT_faccess_control);
+ Opts.AccessControl = !Args.hasArg(OPT_fno_access_control);
Opts.ElideConstructors = !Args.hasArg(OPT_fno_elide_constructors);
Opts.MathErrno = Args.hasArg(OPT_fmath_errno);
- Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 99,
+ Opts.InstantiationDepth = getLastArgIntValue(Args, OPT_ftemplate_depth, 1024,
Diags);
Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
Opts.ObjCConstantStringClass = getLastArgValue(Args,
@@ -1203,7 +1250,9 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args,
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.DumpRecordLayouts = Args.hasArg(OPT_fdump_record_layouts);
+ Opts.DumpVTableLayouts = Args.hasArg(OPT_fdump_vtable_layouts);
+ Opts.NoBitFieldTypeAlign = Args.hasArg(OPT_fno_bitfield_type_align);
Opts.OptimizeSize = 0;
// FIXME: Eliminate this dependency.
@@ -1268,6 +1317,10 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
Opts.Includes.push_back(it->getValue(Args));
}
+ // Include 'altivec.h' if -faltivec option present
+ if (Args.hasArg(OPT_faltivec))
+ Opts.Includes.push_back("altivec.h");
+
for (arg_iterator it = Args.filtered_begin(OPT_remap_file),
ie = Args.filtered_end(); it != ie; ++it) {
std::pair<llvm::StringRef,llvm::StringRef> Split =
diff --git a/lib/Frontend/FixItRewriter.cpp b/lib/Frontend/FixItRewriter.cpp
index 20d452e76a64..7c9a566b6f7f 100644
--- a/lib/Frontend/FixItRewriter.cpp
+++ b/lib/Frontend/FixItRewriter.cpp
@@ -14,6 +14,8 @@
//===----------------------------------------------------------------------===//
#include "clang/Frontend/FixItRewriter.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "llvm/Support/raw_ostream.h"
@@ -24,8 +26,12 @@
using namespace clang;
FixItRewriter::FixItRewriter(Diagnostic &Diags, SourceManager &SourceMgr,
- const LangOptions &LangOpts)
- : Diags(Diags), Rewrite(SourceMgr, LangOpts), NumFailures(0) {
+ const LangOptions &LangOpts,
+ FixItPathRewriter *PathRewriter)
+ : Diags(Diags),
+ Rewrite(SourceMgr, LangOpts),
+ PathRewriter(PathRewriter),
+ NumFailures(0) {
Client = Diags.getClient();
Diags.setClient(this);
}
@@ -34,92 +40,53 @@ FixItRewriter::~FixItRewriter() {
Diags.setClient(Client);
}
-bool FixItRewriter::WriteFixedFile(const std::string &InFileName,
- const std::string &OutFileName) {
+bool FixItRewriter::WriteFixedFile(FileID ID, llvm::raw_ostream &OS) {
+ const RewriteBuffer *RewriteBuf = Rewrite.getRewriteBufferFor(ID);
+ if (!RewriteBuf) return true;
+ RewriteBuf->write(OS);
+ OS.flush();
+ return false;
+}
+
+bool FixItRewriter::WriteFixedFiles() {
if (NumFailures > 0) {
Diag(FullSourceLoc(), diag::warn_fixit_no_changes);
return true;
}
- llvm::OwningPtr<llvm::raw_ostream> OwnedStream;
- llvm::raw_ostream *OutFile;
- if (!OutFileName.empty()) {
- std::string Err;
- OutFile = new llvm::raw_fd_ostream(OutFileName.c_str(), Err,
- llvm::raw_fd_ostream::F_Binary);
- OwnedStream.reset(OutFile);
- } else if (InFileName == "-") {
- OutFile = &llvm::outs();
- } else {
- llvm::sys::Path Path(InFileName);
- std::string Suffix = Path.getSuffix();
- Path.eraseSuffix();
- Path.appendSuffix("fixit." + Suffix);
+ for (iterator I = buffer_begin(), E = buffer_end(); I != E; ++I) {
+ const FileEntry *Entry = Rewrite.getSourceMgr().getFileEntryForID(I->first);
+ std::string Filename = Entry->getName();
+ if (PathRewriter)
+ Filename = PathRewriter->RewriteFilename(Filename);
std::string Err;
- OutFile = new llvm::raw_fd_ostream(Path.c_str(), Err,
- llvm::raw_fd_ostream::F_Binary);
- OwnedStream.reset(OutFile);
- }
-
- FileID MainFileID = Rewrite.getSourceMgr().getMainFileID();
- if (const RewriteBuffer *RewriteBuf =
- Rewrite.getRewriteBufferFor(MainFileID)) {
- *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
- } else {
- Diag(FullSourceLoc(), diag::note_fixit_main_file_unchanged);
+ llvm::raw_fd_ostream OS(Filename.c_str(), Err,
+ llvm::raw_fd_ostream::F_Binary);
+ if (!Err.empty()) {
+ Diags.Report(clang::diag::err_fe_unable_to_open_output)
+ << Filename << Err;
+ continue;
+ }
+ RewriteBuffer &RewriteBuf = I->second;
+ RewriteBuf.write(OS);
+ OS.flush();
}
- OutFile->flush();
return false;
}
bool FixItRewriter::IncludeInDiagnosticCounts() const {
- return Client? Client->IncludeInDiagnosticCounts() : true;
+ return Client ? Client->IncludeInDiagnosticCounts() : true;
}
void FixItRewriter::HandleDiagnostic(Diagnostic::Level DiagLevel,
const DiagnosticInfo &Info) {
Client->HandleDiagnostic(DiagLevel, Info);
- // Skip over any diagnostics that are ignored.
- if (DiagLevel == Diagnostic::Ignored)
+ // Skip over any diagnostics that are ignored or notes.
+ if (DiagLevel <= Diagnostic::Note)
return;
- if (!FixItLocations.empty()) {
- // The user has specified the locations where we should perform
- // the various fix-it modifications.
-
- // If this diagnostic does not have any code modifications,
- // completely ignore it, even if it's an error: fix-it locations
- // are meant to perform specific fix-ups even in the presence of
- // other errors.
- if (Info.getNumFixItHints() == 0)
- return;
-
- // See if the location of the error is one that matches what the
- // user requested.
- bool AcceptableLocation = false;
- const FileEntry *File
- = Rewrite.getSourceMgr().getFileEntryForID(
- Info.getLocation().getFileID());
- unsigned Line = Info.getLocation().getSpellingLineNumber();
- unsigned Column = Info.getLocation().getSpellingColumnNumber();
- for (llvm::SmallVector<RequestedSourceLocation, 4>::iterator
- Loc = FixItLocations.begin(), LocEnd = FixItLocations.end();
- Loc != LocEnd; ++Loc) {
- if (Loc->File == File && Loc->Line == Line && Loc->Column == Column) {
- AcceptableLocation = true;
- break;
- }
- }
-
- if (!AcceptableLocation)
- return;
- } else if (DiagLevel == Diagnostic::Note) {
- // Don't apply fix-it modifications in notes.
- return;
- }
-
// Make sure that we can perform all of the modifications we
// in this diagnostic.
bool CanRewrite = Info.getNumFixItHints() > 0;
@@ -196,3 +163,5 @@ void FixItRewriter::Diag(FullSourceLoc Loc, unsigned DiagID) {
Diags.Report(Loc, DiagID);
Diags.setClient(this);
}
+
+FixItPathRewriter::~FixItPathRewriter() {}
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index 251b8e4cb738..6cd960be20d5 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -19,6 +19,7 @@
#include "clang/Frontend/FixItRewriter.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/Utils.h"
+#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
@@ -74,11 +75,6 @@ ASTConsumer *DeclContextPrintAction::CreateASTConsumer(CompilerInstance &CI,
return CreateDeclContextPrinter();
}
-ASTConsumer *DumpRecordAction::CreateASTConsumer(CompilerInstance &CI,
- llvm::StringRef InFile) {
- return CreateRecordLayoutDumper();
-}
-
ASTConsumer *GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI,
llvm::StringRef InFile) {
const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot;
@@ -118,43 +114,38 @@ ASTConsumer *FixItAction::CreateASTConsumer(CompilerInstance &CI,
return new ASTConsumer();
}
-/// AddFixItLocations - Add any individual user specified "fix-it" locations,
-/// and return true on success.
-static bool AddFixItLocations(CompilerInstance &CI,
- FixItRewriter &FixItRewrite) {
- const std::vector<ParsedSourceLocation> &Locs =
- CI.getFrontendOpts().FixItLocations;
- for (unsigned i = 0, e = Locs.size(); i != e; ++i) {
- const FileEntry *File = CI.getFileManager().getFile(Locs[i].FileName);
- if (!File) {
- CI.getDiagnostics().Report(diag::err_fe_unable_to_find_fixit_file)
- << Locs[i].FileName;
- return false;
- }
-
- RequestedSourceLocation Requested;
- Requested.File = File;
- Requested.Line = Locs[i].Line;
- Requested.Column = Locs[i].Column;
- FixItRewrite.addFixItLocation(Requested);
- }
+class FixItActionSuffixInserter : public FixItPathRewriter {
+ std::string NewSuffix;
- return true;
-}
+public:
+ explicit FixItActionSuffixInserter(std::string NewSuffix)
+ : NewSuffix(NewSuffix) {}
+
+ std::string RewriteFilename(const std::string &Filename) {
+ llvm::sys::Path Path(Filename);
+ std::string Suffix = Path.getSuffix();
+ Path.eraseSuffix();
+ Path.appendSuffix(NewSuffix + "." + Suffix);
+ return Path.c_str();
+ }
+};
bool FixItAction::BeginSourceFileAction(CompilerInstance &CI,
llvm::StringRef Filename) {
+ const FrontendOptions &FEOpts = getCompilerInstance().getFrontendOpts();
+ if (!FEOpts.FixItSuffix.empty()) {
+ PathRewriter.reset(new FixItActionSuffixInserter(FEOpts.FixItSuffix));
+ } else {
+ PathRewriter.reset();
+ }
Rewriter.reset(new FixItRewriter(CI.getDiagnostics(), CI.getSourceManager(),
- CI.getLangOpts()));
- if (!AddFixItLocations(CI, *Rewriter))
- return false;
-
+ CI.getLangOpts(), PathRewriter.get()));
return true;
}
void FixItAction::EndSourceFileAction() {
- const FrontendOptions &FEOpts = getCompilerInstance().getFrontendOpts();
- Rewriter->WriteFixedFile(getCurrentFile(), FEOpts.OutputFile);
+ // Otherwise rewrite all files.
+ Rewriter->WriteFixedFiles();
}
ASTConsumer *RewriteObjCAction::CreateASTConsumer(CompilerInstance &CI,
@@ -197,8 +188,7 @@ void DumpTokensAction::ExecuteAction() {
Preprocessor &PP = getCompilerInstance().getPreprocessor();
// Start preprocessing the specified input file.
Token Tok;
- if (PP.EnterMainSourceFile())
- return;
+ PP.EnterMainSourceFile();
do {
PP.Lex(Tok);
PP.DumpToken(Tok, true);
@@ -212,7 +202,7 @@ void GeneratePTHAction::ExecuteAction() {
CI.getFrontendOpts().OutputFile == "-") {
// FIXME: Don't fail this way.
// FIXME: Verify that we can actually seek in the given file.
- llvm::llvm_report_error("PTH requires a seekable file for output!");
+ llvm::report_fatal_error("PTH requires a seekable file for output!");
}
llvm::raw_fd_ostream *OS =
CI.createDefaultOutputFile(true, getCurrentFile());
@@ -226,8 +216,7 @@ void ParseOnlyAction::ExecuteAction() {
llvm::OwningPtr<Action> PA(new MinimalAction(PP));
Parser P(PP, *PA);
- if (PP.EnterMainSourceFile())
- return;
+ PP.EnterMainSourceFile();
P.ParseTranslationUnit();
}
@@ -236,8 +225,7 @@ void PreprocessOnlyAction::ExecuteAction() {
Token Tok;
// Start parsing the specified input file.
- if (PP.EnterMainSourceFile())
- return;
+ PP.EnterMainSourceFile();
do {
PP.Lex(Tok);
} while (Tok.isNot(tok::eof));
@@ -252,8 +240,7 @@ void PrintParseAction::ExecuteAction() {
llvm::OwningPtr<Action> PA(CreatePrintParserActionsAction(PP, OS));
Parser P(PP, *PA);
- if (PP.EnterMainSourceFile())
- return;
+ PP.EnterMainSourceFile();
P.ParseTranslationUnit();
}
diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp
index 9f5bced0d485..12a4d4dbd094 100644
--- a/lib/Frontend/InitHeaderSearch.cpp
+++ b/lib/Frontend/InitHeaderSearch.cpp
@@ -355,7 +355,7 @@ static bool getVisualStudioDir(std::string &path) {
else if (vs80comntools)
vscomntools = vs80comntools;
if (vscomntools && *vscomntools) {
- char *p = (char*)strstr(vscomntools, "\\Common7\\Tools");
+ char *p = const_cast<char *>(strstr(vscomntools, "\\Common7\\Tools"));
if (p)
*p = '\0';
path = vscomntools;
@@ -429,6 +429,49 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple) {
}
}
break;
+ case llvm::Triple::Haiku:
+ AddPath("/boot/common/include", System, true, false, false);
+ AddPath("/boot/develop/headers/os", System, true, false, false);
+ AddPath("/boot/develop/headers/os/app", System, true, false, false);
+ AddPath("/boot/develop/headers/os/arch", System, true, false, false);
+ AddPath("/boot/develop/headers/os/device", System, true, false, false);
+ AddPath("/boot/develop/headers/os/drivers", System, true, false, false);
+ AddPath("/boot/develop/headers/os/game", System, true, false, false);
+ AddPath("/boot/develop/headers/os/interface", System, true, false, false);
+ AddPath("/boot/develop/headers/os/kernel", System, true, false, false);
+ AddPath("/boot/develop/headers/os/locale", System, true, false, false);
+ AddPath("/boot/develop/headers/os/mail", System, true, false, false);
+ AddPath("/boot/develop/headers/os/media", System, true, false, false);
+ AddPath("/boot/develop/headers/os/midi", System, true, false, false);
+ AddPath("/boot/develop/headers/os/midi2", System, true, false, false);
+ AddPath("/boot/develop/headers/os/net", System, true, false, false);
+ AddPath("/boot/develop/headers/os/storage", System, true, false, false);
+ AddPath("/boot/develop/headers/os/support", System, true, false, false);
+ AddPath("/boot/develop/headers/os/translation",
+ System, true, false, false);
+ AddPath("/boot/develop/headers/os/add-ons/graphics",
+ System, true, false, false);
+ AddPath("/boot/develop/headers/os/add-ons/input_server",
+ System, true, false, false);
+ AddPath("/boot/develop/headers/os/add-ons/screen_saver",
+ System, true, false, false);
+ AddPath("/boot/develop/headers/os/add-ons/tracker",
+ System, true, false, false);
+ AddPath("/boot/develop/headers/os/be_apps/Deskbar",
+ System, true, false, false);
+ AddPath("/boot/develop/headers/os/be_apps/NetPositive",
+ System, true, false, false);
+ AddPath("/boot/develop/headers/os/be_apps/Tracker",
+ System, true, false, false);
+ AddPath("/boot/develop/headers/cpp", System, true, false, false);
+ AddPath("/boot/develop/headers/cpp/i586-pc-haiku",
+ System, true, false, false);
+ AddPath("/boot/develop/headers/3rdparty", System, true, false, false);
+ AddPath("/boot/develop/headers/bsd", System, true, false, false);
+ AddPath("/boot/develop/headers/glibc", System, true, false, false);
+ AddPath("/boot/develop/headers/posix", System, true, false, false);
+ AddPath("/boot/develop/headers", System, true, false, false);
+ break;
case llvm::Triple::MinGW64:
case llvm::Triple::MinGW32:
AddPath("c:/mingw/include", System, true, false, false);
@@ -521,14 +564,26 @@ void InitHeaderSearch::AddDefaultCPlusPlusIncludePaths(const llvm::Triple &tripl
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.1",
"i586-redhat-linux","", "", triple);
+ // Fedora 11 x86_64
+ AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.1",
+ "x86_64-redhat-linux", "32", "", triple);
+
// Fedora 12
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.2",
"i686-redhat-linux","", "", triple);
+ // Fedora 12 x86_64
+ AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.2",
+ "x86_64-redhat-linux", "32", "", triple);
+
// Fedora 12 (February-2010+)
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
"i686-redhat-linux","", "", triple);
-
+
+ // Fedora 12 (February-2010+) x86_64
+ AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
+ "x86_64-redhat-linux", "32", "", 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 8bcd3a83c00e..f1e9819d83ca 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -11,6 +11,7 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/Basic/Version.h"
#include "clang/Frontend/Utils.h"
#include "clang/Basic/MacroBuilder.h"
#include "clang/Basic/TargetInfo.h"
@@ -212,7 +213,20 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
// Compiler version introspection macros.
Builder.defineMacro("__llvm__"); // LLVM Backend
Builder.defineMacro("__clang__"); // Clang Frontend
-
+#define TOSTR2(X) #X
+#define TOSTR(X) TOSTR2(X)
+ Builder.defineMacro("__clang_major__", TOSTR(CLANG_VERSION_MAJOR));
+ Builder.defineMacro("__clang_minor__", TOSTR(CLANG_VERSION_MINOR));
+#ifdef CLANG_VERSION_PATCHLEVEL
+ Builder.defineMacro("__clang_patchlevel__", TOSTR(CLANG_VERSION_PATCHLEVEL));
+#else
+ Builder.defineMacro("__clang_patchlevel__", "0");
+#endif
+ Builder.defineMacro("__clang_version__",
+ "\"" CLANG_VERSION_STRING " ("
+ + getClangFullRepositoryVersion() + ")\"");
+#undef TOSTR
+#undef TOSTR2
// Currently claim to be compatible with GCC 4.2.1-5621.
Builder.defineMacro("__GNUC_MINOR__", "2");
Builder.defineMacro("__GNUC_PATCHLEVEL__", "1");
@@ -294,8 +308,6 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
// C++ translation unit.
Builder.defineMacro("__cplusplus", "199711L");
Builder.defineMacro("__private_extern__", "extern");
- // Ugly hack to work with GNU libstdc++.
- Builder.defineMacro("_GNU_SOURCE");
}
if (LangOpts.Microsoft) {
@@ -503,7 +515,11 @@ void clang::InitializePreprocessor(Preprocessor &PP,
InitializeFileRemapping(PP.getDiagnostics(), PP.getSourceManager(),
PP.getFileManager(), InitOpts);
- Builder.append("# 1 \"<built-in>\" 3");
+ // Emit line markers for various builtin sections of the file. We don't do
+ // this in asm preprocessor mode, because "# 4" is not a line marker directive
+ // in this mode.
+ if (!PP.getLangOptions().AsmPreprocessor)
+ Builder.append("# 1 \"<built-in>\" 3");
// Install things like __POWERPC__, __GNUC__, etc into the macro table.
if (InitOpts.UsePredefines)
@@ -512,7 +528,8 @@ void clang::InitializePreprocessor(Preprocessor &PP,
// Add on the predefines from the driver. Wrap in a #line directive to report
// that they come from the command line.
- Builder.append("# 1 \"<command line>\" 1");
+ if (!PP.getLangOptions().AsmPreprocessor)
+ Builder.append("# 1 \"<command line>\" 1");
// Process #define's and #undef's in the order they are given.
for (unsigned i = 0, e = InitOpts.Macros.size(); i != e; ++i) {
@@ -538,7 +555,8 @@ void clang::InitializePreprocessor(Preprocessor &PP,
}
// Exit the command line and go back to <built-in> (2 is LC_LEAVE).
- Builder.append("# 1 \"<built-in>\" 2");
+ if (!PP.getLangOptions().AsmPreprocessor)
+ Builder.append("# 1 \"<built-in>\" 2");
// Copy PredefinedBuffer into the Preprocessor.
PP.setPredefines(Predefines.str());
diff --git a/lib/Frontend/LangStandards.cpp b/lib/Frontend/LangStandards.cpp
index ed0ea1f45ef6..af1721d0f9ec 100644
--- a/lib/Frontend/LangStandards.cpp
+++ b/lib/Frontend/LangStandards.cpp
@@ -22,7 +22,7 @@ const LangStandard &LangStandard::getLangStandardForKind(Kind K) {
default:
llvm_unreachable("Invalid language kind!");
case lang_unspecified:
- llvm::llvm_report_error("getLangStandardForKind() on unspecified kind");
+ llvm::report_fatal_error("getLangStandardForKind() on unspecified kind");
#define LANGSTANDARD(id, name, desc, features) \
case lang_##id: return Lang_##id;
#include "clang/Frontend/LangStandards.def"
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index b96c04d0a8e0..ae57ce581def 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -62,6 +62,7 @@ PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) {
PARSE_LANGOPT_BENIGN(DollarIdents);
PARSE_LANGOPT_BENIGN(AsmPreprocessor);
PARSE_LANGOPT_IMPORTANT(GNUMode, diag::warn_pch_gnu_extensions);
+ PARSE_LANGOPT_IMPORTANT(GNUKeywords, diag::warn_pch_gnu_keywords);
PARSE_LANGOPT_BENIGN(ImplicitInt);
PARSE_LANGOPT_BENIGN(Digraphs);
PARSE_LANGOPT_BENIGN(HexFloats);
@@ -74,6 +75,8 @@ PCHValidator::ReadLanguageOptions(const LangOptions &LangOpts) {
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_IMPORTANT(NoConstantCFStrings,
+ diag::warn_pch_no_constant_cfstrings);
PARSE_LANGOPT_BENIGN(PascalStrings);
PARSE_LANGOPT_BENIGN(WritableStrings);
PARSE_LANGOPT_IMPORTANT(LaxVectorConversions,
@@ -910,8 +913,14 @@ PCHReader::PCHReadResult PCHReader::ReadSLocEntryRecord(unsigned ID) {
return Failure;
}
- if ((off_t)Record[4] != File->getSize() ||
- (time_t)Record[5] != File->getModificationTime()) {
+ if ((off_t)Record[4] != File->getSize()
+#if !defined(LLVM_ON_WIN32)
+ // In our regression testing, the Windows file system seems to
+ // have inconsistent modification times that sometimes
+ // erroneously trigger this error-handling path.
+ || (time_t)Record[5] != File->getModificationTime()
+#endif
+ ) {
Diag(diag::err_fe_pch_file_modified)
<< Filename;
return Failure;
@@ -1757,17 +1766,16 @@ void PCHReader::InitializeContext(ASTContext &Ctx) {
if (unsigned ObjCClassRedef
= SpecialTypes[pch::SPECIAL_TYPE_OBJC_CLASS_REDEFINITION])
Context->ObjCClassRedefinitionType = GetType(ObjCClassRedef);
-#if 0
- // FIXME. Accommodate for this in several PCH/Index tests
- if (unsigned ObjCSelRedef
- = SpecialTypes[pch::SPECIAL_TYPE_OBJC_SEL_REDEFINITION])
- Context->ObjCSelRedefinitionType = GetType(ObjCSelRedef);
-#endif
if (unsigned String = SpecialTypes[pch::SPECIAL_TYPE_BLOCK_DESCRIPTOR])
Context->setBlockDescriptorType(GetType(String));
if (unsigned String
= SpecialTypes[pch::SPECIAL_TYPE_BLOCK_EXTENDED_DESCRIPTOR])
Context->setBlockDescriptorExtendedType(GetType(String));
+ if (unsigned ObjCSelRedef
+ = SpecialTypes[pch::SPECIAL_TYPE_OBJC_SEL_REDEFINITION])
+ Context->ObjCSelRedefinitionType = GetType(ObjCSelRedef);
+ if (unsigned String = SpecialTypes[pch::SPECIAL_TYPE_NS_CONSTANT_STRING])
+ Context->setNSConstantStringType(GetType(String));
}
/// \brief Retrieve the name of the original source file name
@@ -1879,6 +1887,7 @@ bool PCHReader::ParseLanguageOptions(
PARSE_LANGOPT(DollarIdents);
PARSE_LANGOPT(AsmPreprocessor);
PARSE_LANGOPT(GNUMode);
+ PARSE_LANGOPT(GNUKeywords);
PARSE_LANGOPT(ImplicitInt);
PARSE_LANGOPT(Digraphs);
PARSE_LANGOPT(HexFloats);
@@ -1891,6 +1900,7 @@ bool PCHReader::ParseLanguageOptions(
PARSE_LANGOPT(ObjC2);
PARSE_LANGOPT(ObjCNonFragileABI);
PARSE_LANGOPT(ObjCNonFragileABI2);
+ PARSE_LANGOPT(NoConstantCFStrings);
PARSE_LANGOPT(PascalStrings);
PARSE_LANGOPT(WritableStrings);
PARSE_LANGOPT(LaxVectorConversions);
@@ -2843,6 +2853,14 @@ Selector PCHReader::DecodeSelector(unsigned ID) {
return SelectorsLoaded[Index];
}
+Selector PCHReader::GetSelector(uint32_t ID) {
+ return DecodeSelector(ID);
+}
+
+uint32_t PCHReader::GetNumKnownSelectors() {
+ return TotalNumSelectors + 1;
+}
+
DeclarationName
PCHReader::ReadDeclarationName(const RecordData &Record, unsigned &Idx) {
DeclarationName::NameKind Kind = (DeclarationName::NameKind)Record[Idx++];
diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp
index f847becb15b8..14dd2e927c41 100644
--- a/lib/Frontend/PCHReaderDecl.cpp
+++ b/lib/Frontend/PCHReaderDecl.cpp
@@ -179,6 +179,7 @@ void PCHDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
FD->setPreviousDeclaration(
cast_or_null<FunctionDecl>(Reader.GetDecl(Record[Idx++])));
FD->setStorageClass((FunctionDecl::StorageClass)Record[Idx++]);
+ FD->setStorageClassAsWritten((FunctionDecl::StorageClass)Record[Idx++]);
FD->setInlineSpecified(Record[Idx++]);
FD->setVirtualAsWritten(Record[Idx++]);
FD->setPure(Record[Idx++]);
@@ -196,6 +197,11 @@ void PCHDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
for (unsigned I = 0; I != NumParams; ++I)
Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
FD->setParams(Params.data(), NumParams);
+
+ // FIXME: order this properly w.r.t. friendness
+ // FIXME: this same thing needs to happen for function templates
+ if (FD->isOverloadedOperator() && !FD->getDeclContext()->isRecord())
+ FD->setNonMemberOperator();
}
void PCHDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
@@ -212,6 +218,7 @@ void PCHDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
MD->setSynthesized(Record[Idx++]);
MD->setDeclImplementation((ObjCMethodDecl::ImplementationControl)Record[Idx++]);
MD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record[Idx++]);
+ MD->setNumSelectorArgs(unsigned(Record[Idx++]));
MD->setResultType(Reader.GetType(Record[Idx++]));
MD->setResultTypeSourceInfo(Reader.GetTypeSourceInfo(Record, Idx));
MD->setEndLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
@@ -220,7 +227,8 @@ void PCHDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
Params.reserve(NumParams);
for (unsigned I = 0; I != NumParams; ++I)
Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
- MD->setMethodParams(*Reader.getContext(), Params.data(), NumParams);
+ MD->setMethodParams(*Reader.getContext(), Params.data(), NumParams,
+ NumParams);
}
void PCHDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) {
@@ -375,6 +383,7 @@ void PCHDeclReader::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
VisitObjCImplDecl(D);
D->setSuperClass(
cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+ // FIXME. Add reading of IvarInitializers and NumIvarInitializers.
}
@@ -397,9 +406,11 @@ void PCHDeclReader::VisitFieldDecl(FieldDecl *FD) {
void PCHDeclReader::VisitVarDecl(VarDecl *VD) {
VisitDeclaratorDecl(VD);
VD->setStorageClass((VarDecl::StorageClass)Record[Idx++]);
+ VD->setStorageClassAsWritten((VarDecl::StorageClass)Record[Idx++]);
VD->setThreadSpecified(Record[Idx++]);
VD->setCXXDirectInitializer(Record[Idx++]);
VD->setDeclaredInCondition(Record[Idx++]);
+ VD->setExceptionVariable(Record[Idx++]);
VD->setPreviousDeclaration(
cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
if (Record[Idx++])
@@ -744,7 +755,7 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
break;
case pch::DECL_VAR:
D = VarDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), 0,
- VarDecl::None);
+ VarDecl::None, VarDecl::None);
break;
case pch::DECL_IMPLICIT_PARAM:
@@ -753,7 +764,7 @@ Decl *PCHReader::ReadDeclRecord(uint64_t Offset, unsigned Index) {
case pch::DECL_PARM_VAR:
D = ParmVarDecl::Create(*Context, 0, SourceLocation(), 0, QualType(), 0,
- VarDecl::None, 0);
+ VarDecl::None, VarDecl::None, 0);
break;
case pch::DECL_FILE_SCOPE_ASM:
D = FileScopeAsmDecl::Create(*Context, 0, SourceLocation(), 0);
diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp
index 7b94805d3999..ef6b77026d7f 100644
--- a/lib/Frontend/PCHReaderStmt.cpp
+++ b/lib/Frontend/PCHReaderStmt.cpp
@@ -71,6 +71,7 @@ namespace {
unsigned VisitCharacterLiteral(CharacterLiteral *E);
unsigned VisitParenExpr(ParenExpr *E);
unsigned VisitUnaryOperator(UnaryOperator *E);
+ unsigned VisitOffsetOfExpr(OffsetOfExpr *E);
unsigned VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
unsigned VisitArraySubscriptExpr(ArraySubscriptExpr *E);
unsigned VisitCallExpr(CallExpr *E);
@@ -432,6 +433,49 @@ unsigned PCHStmtReader::VisitUnaryOperator(UnaryOperator *E) {
return 1;
}
+unsigned PCHStmtReader::VisitOffsetOfExpr(OffsetOfExpr *E) {
+ typedef OffsetOfExpr::OffsetOfNode Node;
+ VisitExpr(E);
+ assert(E->getNumComponents() == Record[Idx]);
+ ++Idx;
+ assert(E->getNumExpressions() == Record[Idx]);
+ ++Idx;
+ E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ E->setTypeSourceInfo(Reader.GetTypeSourceInfo(Record, Idx));
+ for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
+ Node::Kind Kind = static_cast<Node::Kind>(Record[Idx++]);
+ SourceLocation Start = SourceLocation::getFromRawEncoding(Record[Idx++]);
+ SourceLocation End = SourceLocation::getFromRawEncoding(Record[Idx++]);
+ switch (Kind) {
+ case Node::Array:
+ E->setComponent(I, Node(Start, Record[Idx++], End));
+ break;
+
+ case Node::Field:
+ E->setComponent(I,
+ Node(Start,
+ dyn_cast_or_null<FieldDecl>(Reader.GetDecl(Record[Idx++])),
+ End));
+ break;
+
+ case Node::Identifier:
+ E->setComponent(I, Node(Start, Reader.GetIdentifier(Record[Idx++]), End));
+ break;
+
+ case Node::Base:
+ // FIXME: Implement this!
+ llvm_unreachable("PCH for offsetof(base-specifier) not implemented");
+ break;
+ }
+ }
+
+ for (unsigned I = 0, N = E->getNumExpressions(); I != N; ++I)
+ E->setIndexExpr(I, cast_or_null<Expr>(StmtStack[StmtStack.size() - N + I]));
+
+ return E->getNumExpressions();
+}
+
unsigned PCHStmtReader::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
VisitExpr(E);
E->setSizeof(Record[Idx++]);
@@ -554,9 +598,9 @@ unsigned PCHStmtReader::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
unsigned PCHStmtReader::VisitInitListExpr(InitListExpr *E) {
VisitExpr(E);
unsigned NumInits = Record[Idx++];
- E->reserveInits(NumInits);
+ E->reserveInits(*Reader.getContext(), NumInits);
for (unsigned I = 0; I != NumInits; ++I)
- E->updateInit(I,
+ E->updateInit(*Reader.getContext(), I,
cast<Expr>(StmtStack[StmtStack.size() - NumInits - 1 + I]));
E->setSyntacticForm(cast_or_null<InitListExpr>(StmtStack.back()));
E->setLBraceLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
@@ -725,7 +769,7 @@ unsigned PCHStmtReader::VisitObjCStringLiteral(ObjCStringLiteral *E) {
unsigned PCHStmtReader::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
VisitExpr(E);
- E->setEncodedType(Reader.GetType(Record[Idx++]));
+ E->setEncodedTypeSourceInfo(Reader.GetTypeSourceInfo(Record, Idx));
E->setAtLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
return 0;
@@ -782,25 +826,42 @@ unsigned PCHStmtReader::VisitObjCImplicitSetterGetterRefExpr(
unsigned PCHStmtReader::VisitObjCMessageExpr(ObjCMessageExpr *E) {
VisitExpr(E);
- E->setNumArgs(Record[Idx++]);
- E->setLeftLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
- E->setRightLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
- E->setSelector(Reader.GetSelector(Record, Idx));
- E->setMethodDecl(cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
-
- E->setReceiver(
+ assert(Record[Idx] == E->getNumArgs());
+ ++Idx;
+ ObjCMessageExpr::ReceiverKind Kind
+ = static_cast<ObjCMessageExpr::ReceiverKind>(Record[Idx++]);
+ switch (Kind) {
+ case ObjCMessageExpr::Instance:
+ E->setInstanceReceiver(
cast_or_null<Expr>(StmtStack[StmtStack.size() - E->getNumArgs() - 1]));
- if (!E->getReceiver()) {
- ObjCMessageExpr::ClassInfo CI;
- CI.Decl = cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++]));
- CI.Name = Reader.GetIdentifierInfo(Record, Idx);
- CI.Loc = SourceLocation::getFromRawEncoding(Record[Idx++]);
- E->setClassInfo(CI);
+ break;
+
+ case ObjCMessageExpr::Class:
+ E->setClassReceiver(Reader.GetTypeSourceInfo(Record, Idx));
+ break;
+
+ case ObjCMessageExpr::SuperClass:
+ case ObjCMessageExpr::SuperInstance: {
+ QualType T = Reader.GetType(Record[Idx++]);
+ SourceLocation SuperLoc = SourceLocation::getFromRawEncoding(Record[Idx++]);
+ E->setSuper(SuperLoc, T, Kind == ObjCMessageExpr::SuperInstance);
+ break;
}
+ }
+
+ assert(Kind == E->getReceiverKind());
+
+ if (Record[Idx++])
+ E->setMethodDecl(cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
+ else
+ E->setSelector(Reader.GetSelector(Record, Idx));
+
+ E->setLeftLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+ E->setRightLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
E->setArg(I, cast<Expr>(StmtStack[StmtStack.size() - N + I]));
- return E->getNumArgs() + 1;
+ return E->getNumArgs() + (Kind == ObjCMessageExpr::Instance);
}
unsigned PCHStmtReader::VisitObjCSuperExpr(ObjCSuperExpr *E) {
@@ -821,12 +882,11 @@ unsigned PCHStmtReader::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
unsigned PCHStmtReader::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
VisitStmt(S);
- S->setCatchBody(cast_or_null<Stmt>(StmtStack[StmtStack.size() - 2]));
- S->setNextCatchStmt(cast_or_null<Stmt>(StmtStack[StmtStack.size() - 1]));
- S->setCatchParamDecl(cast_or_null<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
+ S->setCatchBody(cast_or_null<Stmt>(StmtStack.back()));
+ S->setCatchParamDecl(cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++])));
S->setAtCatchLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
S->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
- return 2;
+ return 1;
}
unsigned PCHStmtReader::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
@@ -838,11 +898,21 @@ unsigned PCHStmtReader::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
unsigned PCHStmtReader::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
VisitStmt(S);
- S->setTryBody(cast_or_null<Stmt>(StmtStack[StmtStack.size() - 3]));
- S->setCatchStmts(cast_or_null<Stmt>(StmtStack[StmtStack.size() - 2]));
- S->setFinallyStmt(cast_or_null<Stmt>(StmtStack[StmtStack.size() - 1]));
+ assert(Record[Idx] == S->getNumCatchStmts());
+ ++Idx;
+ bool HasFinally = Record[Idx++];
+ for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
+ unsigned Offset = StmtStack.size() - N - HasFinally + I;
+ S->setCatchStmt(I, cast_or_null<ObjCAtCatchStmt>(StmtStack[Offset]));
+ }
+
+ unsigned TryOffset
+ = StmtStack.size() - S->getNumCatchStmts() - HasFinally - 1;
+ S->setTryBody(cast_or_null<Stmt>(StmtStack[TryOffset]));
+ if (HasFinally)
+ S->setFinallyStmt(cast_or_null<Stmt>(StmtStack[StmtStack.size() - 1]));
S->setAtTryLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
- return 3;
+ return 1 + S->getNumCatchStmts() + HasFinally;
}
unsigned PCHStmtReader::VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
@@ -1079,6 +1149,12 @@ Stmt *PCHReader::ReadStmt(llvm::BitstreamCursor &Cursor) {
S = new (Context) UnaryOperator(Empty);
break;
+ case pch::EXPR_OFFSETOF:
+ S = OffsetOfExpr::CreateEmpty(*Context,
+ Record[PCHStmtReader::NumExprFields],
+ Record[PCHStmtReader::NumExprFields + 1]);
+ break;
+
case pch::EXPR_SIZEOF_ALIGN_OF:
S = new (Context) SizeOfAlignOfExpr(Empty);
break;
@@ -1124,7 +1200,7 @@ Stmt *PCHReader::ReadStmt(llvm::BitstreamCursor &Cursor) {
break;
case pch::EXPR_INIT_LIST:
- S = new (Context) InitListExpr(Empty);
+ S = new (Context) InitListExpr(*getContext(), Empty);
break;
case pch::EXPR_DESIGNATED_INIT:
@@ -1195,7 +1271,8 @@ Stmt *PCHReader::ReadStmt(llvm::BitstreamCursor &Cursor) {
S = new (Context) ObjCImplicitSetterGetterRefExpr(Empty);
break;
case pch::EXPR_OBJC_MESSAGE_EXPR:
- S = new (Context) ObjCMessageExpr(Empty);
+ S = ObjCMessageExpr::CreateEmpty(*Context,
+ Record[PCHStmtReader::NumExprFields]);
break;
case pch::EXPR_OBJC_SUPER_EXPR:
S = new (Context) ObjCSuperExpr(Empty);
@@ -1213,7 +1290,9 @@ Stmt *PCHReader::ReadStmt(llvm::BitstreamCursor &Cursor) {
S = new (Context) ObjCAtFinallyStmt(Empty);
break;
case pch::STMT_OBJC_AT_TRY:
- S = new (Context) ObjCAtTryStmt(Empty);
+ S = ObjCAtTryStmt::CreateEmpty(*Context,
+ Record[PCHStmtReader::NumStmtFields],
+ Record[PCHStmtReader::NumStmtFields + 1]);
break;
case pch::STMT_OBJC_AT_SYNCHRONIZED:
S = new (Context) ObjCAtSynchronizedStmt(Empty);
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index 4dd8dc36b760..e56dd3132224 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -1,4 +1,4 @@
-//===--- PCHWriter.h - Precompiled Headers Writer ---------------*- C++ -*-===//
+//===--- PCHWriter.cpp - Precompiled Headers Writer -----------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -63,6 +63,7 @@ namespace {
#define ABSTRACT_TYPE(Class, Base)
#define DEPENDENT_TYPE(Class, Base)
#include "clang/AST/TypeNodes.def"
+ void VisitInjectedClassNameType(const InjectedClassNameType *T);
};
}
@@ -240,7 +241,7 @@ void PCHTypeWriter::VisitQualifiedNameType(const QualifiedNameType *T) {
void PCHTypeWriter::VisitInjectedClassNameType(const InjectedClassNameType *T) {
Writer.AddDeclRef(T->getDecl(), Record);
- Writer.AddTypeRef(T->getUnderlyingType(), Record);
+ Writer.AddTypeRef(T->getInjectedSpecializationType(), Record);
Code = pch::TYPE_INJECTED_CLASS_NAME;
}
@@ -745,6 +746,7 @@ void PCHWriter::WriteLanguageOptions(const LangOptions &LangOpts) {
Record.push_back(LangOpts.DollarIdents); // '$' allowed in identifiers.
Record.push_back(LangOpts.AsmPreprocessor); // Preprocessor in asm mode.
Record.push_back(LangOpts.GNUMode); // True in gnu99 mode false in c99 mode (etc)
+ Record.push_back(LangOpts.GNUKeywords); // Allow GNU-extension keywords
Record.push_back(LangOpts.ImplicitInt); // C89 implicit 'int'.
Record.push_back(LangOpts.Digraphs); // C94, C99 and C++
Record.push_back(LangOpts.HexFloats); // C99 Hexadecimal float constants.
@@ -760,6 +762,7 @@ void PCHWriter::WriteLanguageOptions(const LangOptions &LangOpts) {
// modern abi enabled.
Record.push_back(LangOpts.ObjCNonFragileABI2); // Objective-C enhanced
// modern abi enabled.
+ Record.push_back(LangOpts.NoConstantCFStrings); // non cfstring generation enabled..
Record.push_back(LangOpts.PascalStrings); // Allow Pascal strings
Record.push_back(LangOpts.WritableStrings); // Allow writable strings
@@ -1103,7 +1106,7 @@ void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
// that is required by llvm::MemoryBuffer::getMemBuffer (on
// the reader side).
const llvm::MemoryBuffer *Buffer
- = Content->getBuffer(PP.getDiagnostics());
+ = Content->getBuffer(PP.getDiagnostics(), PP.getSourceManager());
const char *Name = Buffer->getBufferIdentifier();
Stream.EmitRecordWithBlob(SLocBufferAbbrv, Record,
llvm::StringRef(Name, strlen(Name) + 1));
@@ -2093,12 +2096,10 @@ void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,
AddTypeRef(Context.getsigjmp_bufType(), Record);
AddTypeRef(Context.ObjCIdRedefinitionType, Record);
AddTypeRef(Context.ObjCClassRedefinitionType, Record);
-#if 0
- // FIXME. Accommodate for this in several PCH/Indexer tests
- AddTypeRef(Context.ObjCSelRedefinitionType, Record);
-#endif
AddTypeRef(Context.getRawBlockdescriptorType(), Record);
AddTypeRef(Context.getRawBlockdescriptorExtendedType(), Record);
+ AddTypeRef(Context.ObjCSelRedefinitionType, Record);
+ AddTypeRef(Context.getRawNSConstantStringType(), Record);
Stream.EmitRecord(pch::SPECIAL_TYPES, Record);
// Keep writing types and declarations until all types and
diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp
index 7917280295ad..7b7806239604 100644
--- a/lib/Frontend/PCHWriterDecl.cpp
+++ b/lib/Frontend/PCHWriterDecl.cpp
@@ -176,6 +176,7 @@ void PCHDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
Writer.AddStmt(D->getBody());
Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
Record.push_back(D->getStorageClass()); // FIXME: stable encoding
+ Record.push_back(D->getStorageClassAsWritten());
Record.push_back(D->isInlineSpecified());
Record.push_back(D->isVirtualAsWritten());
Record.push_back(D->isPure());
@@ -211,6 +212,7 @@ void PCHDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
Record.push_back(D->getImplementationControl());
// FIXME: stable encoding for in/out/inout/bycopy/byref/oneway
Record.push_back(D->getObjCDeclQualifier());
+ Record.push_back(D->getNumSelectorArgs());
Writer.AddTypeRef(D->getResultType(), Record);
Writer.AddTypeSourceInfo(D->getResultTypeSourceInfo(), Record);
Writer.AddSourceLocation(D->getLocEnd(), Record);
@@ -359,6 +361,7 @@ void PCHDeclWriter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
void PCHDeclWriter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
VisitObjCImplDecl(D);
Writer.AddDeclRef(D->getSuperClass(), Record);
+ // FIXME add writing of IvarInitializers and NumIvarInitializers.
Code = pch::DECL_OBJC_IMPLEMENTATION;
}
@@ -382,9 +385,11 @@ void PCHDeclWriter::VisitFieldDecl(FieldDecl *D) {
void PCHDeclWriter::VisitVarDecl(VarDecl *D) {
VisitDeclaratorDecl(D);
Record.push_back(D->getStorageClass()); // FIXME: stable encoding
+ Record.push_back(D->getStorageClassAsWritten());
Record.push_back(D->isThreadSpecified());
Record.push_back(D->hasCXXDirectInitializer());
Record.push_back(D->isDeclaredInCondition());
+ Record.push_back(D->isExceptionVariable());
Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
Record.push_back(D->getInit()? 1 : 0);
if (D->getInit())
@@ -425,6 +430,7 @@ void PCHDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {
assert(!D->isThreadSpecified() && "PARM_VAR_DECL can't be __thread");
assert(D->getAccess() == AS_none && "PARM_VAR_DECL can't be public/private");
assert(!D->isDeclaredInCondition() && "PARM_VAR_DECL can't be in condition");
+ assert(!D->isExceptionVariable() && "PARM_VAR_DECL can't be exception var");
assert(D->getPreviousDeclaration() == 0 && "PARM_VAR_DECL can't be redecl");
assert(D->getInit() == 0 && "PARM_VAR_DECL never has init");
}
@@ -493,9 +499,11 @@ void PCHWriter::WriteDeclsBlockAbbrevs() {
Abv->Add(BitCodeAbbrevOp(pch::PREDEF_TYPE_NULL_ID)); // InfoType
// VarDecl
Abv->Add(BitCodeAbbrevOp(0)); // StorageClass
+ Abv->Add(BitCodeAbbrevOp(0)); // StorageClassAsWritten
Abv->Add(BitCodeAbbrevOp(0)); // isThreadSpecified
Abv->Add(BitCodeAbbrevOp(0)); // hasCXXDirectInitializer
Abv->Add(BitCodeAbbrevOp(0)); // isDeclaredInCondition
+ Abv->Add(BitCodeAbbrevOp(0)); // isExceptionVariable
Abv->Add(BitCodeAbbrevOp(0)); // PrevDecl
Abv->Add(BitCodeAbbrevOp(0)); // HasInit
// ParmVarDecl
@@ -608,7 +616,7 @@ void PCHWriter::WriteDecl(ASTContext &Context, Decl *D) {
if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset);
if (!W.Code)
- llvm::llvm_report_error(llvm::StringRef("unexpected declaration kind '") +
+ llvm::report_fatal_error(llvm::StringRef("unexpected declaration kind '") +
D->getDeclKindName() + "'");
Stream.EmitRecord(W.Code, Record, W.AbbrevToUse);
diff --git a/lib/Frontend/PCHWriterStmt.cpp b/lib/Frontend/PCHWriterStmt.cpp
index 9a5417ca6102..a1993d37f2dc 100644
--- a/lib/Frontend/PCHWriterStmt.cpp
+++ b/lib/Frontend/PCHWriterStmt.cpp
@@ -62,6 +62,7 @@ namespace {
void VisitCharacterLiteral(CharacterLiteral *E);
void VisitParenExpr(ParenExpr *E);
void VisitUnaryOperator(UnaryOperator *E);
+ void VisitOffsetOfExpr(OffsetOfExpr *E);
void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
void VisitArraySubscriptExpr(ArraySubscriptExpr *E);
void VisitCallExpr(CallExpr *E);
@@ -393,6 +394,42 @@ void PCHStmtWriter::VisitUnaryOperator(UnaryOperator *E) {
Code = pch::EXPR_UNARY_OPERATOR;
}
+void PCHStmtWriter::VisitOffsetOfExpr(OffsetOfExpr *E) {
+ VisitExpr(E);
+ Record.push_back(E->getNumComponents());
+ Record.push_back(E->getNumExpressions());
+ Writer.AddSourceLocation(E->getOperatorLoc(), Record);
+ Writer.AddSourceLocation(E->getRParenLoc(), Record);
+ Writer.AddTypeSourceInfo(E->getTypeSourceInfo(), Record);
+ for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
+ const OffsetOfExpr::OffsetOfNode &ON = E->getComponent(I);
+ Record.push_back(ON.getKind()); // FIXME: Stable encoding
+ Writer.AddSourceLocation(ON.getRange().getBegin(), Record);
+ Writer.AddSourceLocation(ON.getRange().getEnd(), Record);
+ switch (ON.getKind()) {
+ case OffsetOfExpr::OffsetOfNode::Array:
+ Record.push_back(ON.getArrayExprIndex());
+ break;
+
+ case OffsetOfExpr::OffsetOfNode::Field:
+ Writer.AddDeclRef(ON.getField(), Record);
+ break;
+
+ case OffsetOfExpr::OffsetOfNode::Identifier:
+ Writer.AddIdentifierRef(ON.getFieldName(), Record);
+ break;
+
+ case OffsetOfExpr::OffsetOfNode::Base:
+ // FIXME: Implement this!
+ llvm_unreachable("PCH for offsetof(base-specifier) not implemented");
+ break;
+ }
+ }
+ for (unsigned I = 0, N = E->getNumExpressions(); I != N; ++I)
+ Writer.WriteSubStmt(E->getIndexExpr(I));
+ Code = pch::EXPR_OFFSETOF;
+}
+
void PCHStmtWriter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
VisitExpr(E);
Record.push_back(E->isSizeOf());
@@ -655,7 +692,7 @@ void PCHStmtWriter::VisitObjCStringLiteral(ObjCStringLiteral *E) {
void PCHStmtWriter::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
VisitExpr(E);
- Writer.AddTypeRef(E->getEncodedType(), Record);
+ Writer.AddTypeSourceInfo(E->getEncodedTypeSourceInfo(), Record);
Writer.AddSourceLocation(E->getAtLoc(), Record);
Writer.AddSourceLocation(E->getRParenLoc(), Record);
Code = pch::EXPR_OBJC_ENCODE;
@@ -712,18 +749,33 @@ void PCHStmtWriter::VisitObjCImplicitSetterGetterRefExpr(
void PCHStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
VisitExpr(E);
Record.push_back(E->getNumArgs());
+ Record.push_back((unsigned)E->getReceiverKind()); // FIXME: stable encoding
+ switch (E->getReceiverKind()) {
+ case ObjCMessageExpr::Instance:
+ Writer.WriteSubStmt(E->getInstanceReceiver());
+ break;
+
+ case ObjCMessageExpr::Class:
+ Writer.AddTypeSourceInfo(E->getClassReceiverTypeInfo(), Record);
+ break;
+
+ case ObjCMessageExpr::SuperClass:
+ case ObjCMessageExpr::SuperInstance:
+ Writer.AddTypeRef(E->getSuperType(), Record);
+ Writer.AddSourceLocation(E->getSuperLoc(), Record);
+ break;
+ }
+
+ if (E->getMethodDecl()) {
+ Record.push_back(1);
+ Writer.AddDeclRef(E->getMethodDecl(), Record);
+ } else {
+ Record.push_back(0);
+ Writer.AddSelectorRef(E->getSelector(), Record);
+ }
+
Writer.AddSourceLocation(E->getLeftLoc(), Record);
Writer.AddSourceLocation(E->getRightLoc(), Record);
- Writer.AddSelectorRef(E->getSelector(), Record);
- Writer.AddDeclRef(E->getMethodDecl(), Record); // optional
- Writer.WriteSubStmt(E->getReceiver());
-
- if (!E->getReceiver()) {
- ObjCMessageExpr::ClassInfo CI = E->getClassInfo();
- Writer.AddDeclRef(CI.Decl, Record);
- Writer.AddIdentifierRef(CI.Name, Record);
- Writer.AddSourceLocation(CI.Loc, Record);
- }
for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
Arg != ArgEnd; ++Arg)
@@ -749,7 +801,6 @@ void PCHStmtWriter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
void PCHStmtWriter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
Writer.WriteSubStmt(S->getCatchBody());
- Writer.WriteSubStmt(S->getNextCatchStmt());
Writer.AddDeclRef(S->getCatchParamDecl(), Record);
Writer.AddSourceLocation(S->getAtCatchLoc(), Record);
Writer.AddSourceLocation(S->getRParenLoc(), Record);
@@ -763,9 +814,13 @@ void PCHStmtWriter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
}
void PCHStmtWriter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
+ Record.push_back(S->getNumCatchStmts());
+ Record.push_back(S->getFinallyStmt() != 0);
Writer.WriteSubStmt(S->getTryBody());
- Writer.WriteSubStmt(S->getCatchStmts());
- Writer.WriteSubStmt(S->getFinallyStmt());
+ for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I)
+ Writer.WriteSubStmt(S->getCatchStmt(I));
+ if (S->getFinallyStmt())
+ Writer.WriteSubStmt(S->getFinallyStmt());
Writer.AddSourceLocation(S->getAtTryLoc(), Record);
Code = pch::STMT_OBJC_AT_TRY;
}
diff --git a/lib/Frontend/PrintParserCallbacks.cpp b/lib/Frontend/PrintParserCallbacks.cpp
index 8d64a6413304..4df5c5263c7e 100644
--- a/lib/Frontend/PrintParserCallbacks.cpp
+++ b/lib/Frontend/PrintParserCallbacks.cpp
@@ -197,7 +197,7 @@ namespace {
}
virtual DeclPtrTy ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
- SourceLocation KWLoc, const CXXScopeSpec &SS,
+ SourceLocation KWLoc, CXXScopeSpec &SS,
IdentifierInfo *Name, SourceLocation NameLoc,
AttributeList *Attr, AccessSpecifier AS,
MultiTemplateParamsArg TemplateParameterLists,
@@ -405,8 +405,8 @@ namespace {
// Objective-c statements
virtual OwningStmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc,
SourceLocation RParen,
- DeclPtrTy Parm, StmtArg Body,
- StmtArg CatchList) {
+ DeclPtrTy Parm,
+ StmtArg Body) {
Out << __FUNCTION__ << "\n";
return StmtEmpty();
}
@@ -418,7 +418,8 @@ namespace {
}
virtual OwningStmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc,
- StmtArg Try, StmtArg Catch,
+ StmtArg Try,
+ MultiStmtArg CatchStmts,
StmtArg Finally) {
Out << __FUNCTION__ << "\n";
return StmtEmpty();
diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp
index 02afd24c246e..b6c18b77316c 100644
--- a/lib/Frontend/PrintPreprocessedOutput.cpp
+++ b/lib/Frontend/PrintPreprocessedOutput.cpp
@@ -78,6 +78,7 @@ static void PrintMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI,
namespace {
class PrintPPOutputPPCallbacks : public PPCallbacks {
Preprocessor &PP;
+ SourceManager &SM;
TokenConcatenation ConcatInfo;
public:
llvm::raw_ostream &OS;
@@ -94,7 +95,8 @@ private:
public:
PrintPPOutputPPCallbacks(Preprocessor &pp, llvm::raw_ostream &os,
bool lineMarkers, bool defines)
- : PP(pp), ConcatInfo(PP), OS(os), DisableLineMarkers(lineMarkers),
+ : PP(pp), SM(PP.getSourceManager()),
+ ConcatInfo(PP), OS(os), DisableLineMarkers(lineMarkers),
DumpDefines(defines) {
CurLine = 0;
CurFilename += "<uninit>";
@@ -118,9 +120,14 @@ public:
bool HandleFirstTokOnLine(Token &Tok);
- bool MoveToLine(SourceLocation Loc);
- bool AvoidConcat(const Token &PrevTok, const Token &Tok) {
- return ConcatInfo.AvoidConcat(PrevTok, Tok);
+ bool MoveToLine(SourceLocation Loc) {
+ return MoveToLine(SM.getPresumedLoc(Loc).getLine());
+ }
+ bool MoveToLine(unsigned LineNo);
+
+ bool AvoidConcat(const Token &PrevPrevTok, const Token &PrevTok,
+ const Token &Tok) {
+ return ConcatInfo.AvoidConcat(PrevPrevTok, PrevTok, Tok);
}
void WriteLineInfo(unsigned LineNo, const char *Extra=0, unsigned ExtraLen=0);
@@ -166,9 +173,7 @@ void PrintPPOutputPPCallbacks::WriteLineInfo(unsigned LineNo,
/// object. We can do this by emitting some number of \n's, or be emitting a
/// #line directive. This returns false if already at the specified line, true
/// if some newlines were emitted.
-bool PrintPPOutputPPCallbacks::MoveToLine(SourceLocation Loc) {
- unsigned LineNo = PP.getSourceManager().getInstantiationLineNumber(Loc);
-
+bool PrintPPOutputPPCallbacks::MoveToLine(unsigned LineNo) {
if (DisableLineMarkers) {
if (LineNo == CurLine) return false;
@@ -211,27 +216,29 @@ void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc,
SrcMgr::CharacteristicKind NewFileType) {
// Unless we are exiting a #include, make sure to skip ahead to the line the
// #include directive was at.
- SourceManager &SourceMgr = PP.getSourceManager();
+ SourceManager &SourceMgr = SM;
+
+ PresumedLoc UserLoc = SourceMgr.getPresumedLoc(Loc);
+ unsigned NewLine = UserLoc.getLine();
+
if (Reason == PPCallbacks::EnterFile) {
SourceLocation IncludeLoc = SourceMgr.getPresumedLoc(Loc).getIncludeLoc();
if (IncludeLoc.isValid())
MoveToLine(IncludeLoc);
} else if (Reason == PPCallbacks::SystemHeaderPragma) {
- MoveToLine(Loc);
+ MoveToLine(NewLine);
// TODO GCC emits the # directive for this directive on the line AFTER the
// directive and emits a bunch of spaces that aren't needed. Emulate this
// strange behavior.
}
-
- Loc = SourceMgr.getInstantiationLoc(Loc);
- // FIXME: Should use presumed line #!
- CurLine = SourceMgr.getInstantiationLineNumber(Loc);
+
+ CurLine = NewLine;
if (DisableLineMarkers) return;
CurFilename.clear();
- CurFilename += SourceMgr.getPresumedLoc(Loc).getFilename();
+ CurFilename += UserLoc.getFilename();
Lexer::Stringify(CurFilename);
FileType = NewFileType;
@@ -318,8 +325,7 @@ bool PrintPPOutputPPCallbacks::HandleFirstTokOnLine(Token &Tok) {
// Print out space characters so that the first token on a line is
// indented for easy reading.
- const SourceManager &SourceMgr = PP.getSourceManager();
- unsigned ColNo = SourceMgr.getInstantiationColumnNumber(Tok.getLocation());
+ unsigned ColNo = SM.getInstantiationColumnNumber(Tok.getLocation());
// This hack prevents stuff like:
// #define HASH #
@@ -391,6 +397,7 @@ static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok,
PrintPPOutputPPCallbacks *Callbacks,
llvm::raw_ostream &OS) {
char Buffer[256];
+ Token PrevPrevTok;
Token PrevTok;
while (1) {
@@ -402,7 +409,7 @@ static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok,
// useful to look at and no concatenation could happen anyway.
(Callbacks->hasEmittedTokensOnThisLine() &&
// Don't print "-" next to "-", it would form "--".
- Callbacks->AvoidConcat(PrevTok, Tok))) {
+ Callbacks->AvoidConcat(PrevPrevTok, PrevTok, Tok))) {
OS << ' ';
}
@@ -433,6 +440,7 @@ static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok,
if (Tok.is(tok::eof)) break;
+ PrevPrevTok = PrevTok;
PrevTok = Tok;
PP.Lex(Tok);
}
@@ -448,8 +456,7 @@ static int MacroIDCompare(const void* a, const void* b) {
static void DoPrintMacros(Preprocessor &PP, llvm::raw_ostream *OS) {
// -dM mode just scans and ignores all tokens in the files, then dumps out
// the macro table at the end.
- if (PP.EnterMainSourceFile())
- return;
+ PP.EnterMainSourceFile();
Token Tok;
do PP.Lex(Tok);
@@ -484,8 +491,6 @@ void clang::DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream *OS,
// to -C or -CC.
PP.SetCommentRetentionState(Opts.ShowComments, Opts.ShowMacroComments);
- OS->SetBufferSize(64*1024);
-
PrintPPOutputPPCallbacks *Callbacks =
new PrintPPOutputPPCallbacks(PP, *OS, !Opts.ShowLineMarkers,
Opts.ShowMacros);
@@ -496,8 +501,7 @@ void clang::DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream *OS,
PP.addPPCallbacks(Callbacks);
// After we have configured the preprocessor, enter the main file.
- if (PP.EnterMainSourceFile())
- return;
+ PP.EnterMainSourceFile();
// Consume all of the tokens that come from the predefines buffer. Those
// should not be emitted into the output and are guaranteed to be at the
diff --git a/lib/Frontend/RewriteMacros.cpp b/lib/Frontend/RewriteMacros.cpp
index 4ffb2978db7a..954e8e23cac7 100644
--- a/lib/Frontend/RewriteMacros.cpp
+++ b/lib/Frontend/RewriteMacros.cpp
@@ -101,8 +101,7 @@ void clang::RewriteMacrosInInput(Preprocessor &PP, llvm::raw_ostream *OS) {
// Get the first preprocessing token.
- if (PP.EnterMainSourceFile())
- return;
+ PP.EnterMainSourceFile();
Token PPTok;
PP.Lex(PPTok);
diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp
index cba92987a3d6..11698325e9b1 100644
--- a/lib/Frontend/RewriteObjC.cpp
+++ b/lib/Frontend/RewriteObjC.cpp
@@ -444,7 +444,7 @@ namespace {
CStyleCastExpr* NoTypeInfoCStyleCastExpr(ASTContext *Ctx, QualType Ty,
CastExpr::CastKind Kind, Expr *E) {
TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation());
- return new (Ctx) CStyleCastExpr(Ty, Kind, E, TInfo,
+ return new (Ctx) CStyleCastExpr(Ty, Kind, E, CXXBaseSpecifierArray(), TInfo,
SourceLocation(), SourceLocation());
}
}
@@ -640,7 +640,9 @@ void RewriteObjC::Initialize(ASTContext &context) {
if (LangOpts.Microsoft) {
Preamble += "#undef __OBJC_RW_DLLIMPORT\n";
Preamble += "#undef __OBJC_RW_STATICIMPORT\n";
+ Preamble += "#ifndef KEEP_ATTRIBUTES\n"; // We use this for clang tests.
Preamble += "#define __attribute__(X)\n";
+ Preamble += "#endif\n";
Preamble += "#define __weak\n";
}
else {
@@ -1237,11 +1239,26 @@ Stmt *RewriteObjC::RewritePropertySetter(BinaryOperator *BinOp, Expr *newStmt,
// This allows us to handle chain/nested property getters.
Receiver = PropGetters[PRE];
}
- MsgExpr = new (Context) ObjCMessageExpr(*Context, dyn_cast<Expr>(Receiver),
- PDecl->getSetterName(), PDecl->getType(),
- PDecl->getSetterMethodDecl(),
- SourceLocation(), SourceLocation(),
- &ExprVec[0], 1);
+ if (isa<ObjCSuperExpr>(Receiver))
+ MsgExpr = ObjCMessageExpr::Create(*Context,
+ PDecl->getType().getNonReferenceType(),
+ /*FIXME?*/SourceLocation(),
+ Receiver->getLocStart(),
+ /*IsInstanceSuper=*/true,
+ cast<Expr>(Receiver)->getType(),
+ PDecl->getSetterName(),
+ PDecl->getSetterMethodDecl(),
+ &ExprVec[0], 1,
+ /*FIXME:*/SourceLocation());
+ else
+ MsgExpr = ObjCMessageExpr::Create(*Context,
+ PDecl->getType().getNonReferenceType(),
+ /*FIXME: */SourceLocation(),
+ cast<Expr>(Receiver),
+ PDecl->getSetterName(),
+ PDecl->getSetterMethodDecl(),
+ &ExprVec[0], 1,
+ /*FIXME:*/SourceLocation());
Stmt *ReplacingStmt = SynthMessageExpr(MsgExpr);
// Now do the actual rewrite.
@@ -1266,11 +1283,27 @@ Stmt *RewriteObjC::RewritePropertyGetter(ObjCPropertyRefExpr *PropRefExpr) {
// This allows us to handle chain/nested property getters.
Receiver = PropGetters[PRE];
}
- MsgExpr = new (Context) ObjCMessageExpr(*Context, dyn_cast<Expr>(Receiver),
- PDecl->getGetterName(), PDecl->getType(),
- PDecl->getGetterMethodDecl(),
- SourceLocation(), SourceLocation(),
- 0, 0);
+
+ if (isa<ObjCSuperExpr>(Receiver))
+ MsgExpr = ObjCMessageExpr::Create(*Context,
+ PDecl->getType().getNonReferenceType(),
+ /*FIXME:*/SourceLocation(),
+ Receiver->getLocStart(),
+ /*IsInstanceSuper=*/true,
+ cast<Expr>(Receiver)->getType(),
+ PDecl->getGetterName(),
+ PDecl->getGetterMethodDecl(),
+ 0, 0,
+ /*FIXME:*/SourceLocation());
+ else
+ MsgExpr = ObjCMessageExpr::Create(*Context,
+ PDecl->getType().getNonReferenceType(),
+ /*FIXME:*/SourceLocation(),
+ cast<Expr>(Receiver),
+ PDecl->getGetterName(),
+ PDecl->getGetterMethodDecl(),
+ 0, 0,
+ /*FIXME:*/SourceLocation());
Stmt *ReplacingStmt = SynthMessageExpr(MsgExpr);
@@ -1828,8 +1861,7 @@ Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
assert((*startBuf == '}') && "bogus @try block");
SourceLocation lastCurlyLoc = startLoc;
- ObjCAtCatchStmt *catchList = S->getCatchStmts();
- if (catchList) {
+ if (S->getNumCatchStmts()) {
startLoc = startLoc.getFileLocWithOffset(1);
buf = " /* @catch begin */ else {\n";
buf += " id _caught = objc_exception_extract(&_stack);\n";
@@ -1847,26 +1879,27 @@ Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
}
bool sawIdTypedCatch = false;
Stmt *lastCatchBody = 0;
- while (catchList) {
- ParmVarDecl *catchDecl = catchList->getCatchParamDecl();
+ for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
+ ObjCAtCatchStmt *Catch = S->getCatchStmt(I);
+ VarDecl *catchDecl = Catch->getCatchParamDecl();
- if (catchList == S->getCatchStmts())
+ if (I == 0)
buf = "if ("; // we are generating code for the first catch clause
else
buf = "else if (";
- startLoc = catchList->getLocStart();
+ startLoc = Catch->getLocStart();
startBuf = SM->getCharacterData(startLoc);
assert((*startBuf == '@') && "bogus @catch location");
const char *lParenLoc = strchr(startBuf, '(');
- if (catchList->hasEllipsis()) {
+ if (Catch->hasEllipsis()) {
// Now rewrite the body...
- lastCatchBody = catchList->getCatchBody();
+ lastCatchBody = Catch->getCatchBody();
SourceLocation bodyLoc = lastCatchBody->getLocStart();
const char *bodyBuf = SM->getCharacterData(bodyLoc);
- assert(*SM->getCharacterData(catchList->getRParenLoc()) == ')' &&
+ assert(*SM->getCharacterData(Catch->getRParenLoc()) == ')' &&
"bogus @catch paren location");
assert((*bodyBuf == '{') && "bogus @catch body location");
@@ -1890,8 +1923,8 @@ Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
}
}
// Now rewrite the body...
- lastCatchBody = catchList->getCatchBody();
- SourceLocation rParenLoc = catchList->getRParenLoc();
+ lastCatchBody = Catch->getCatchBody();
+ SourceLocation rParenLoc = Catch->getRParenLoc();
SourceLocation bodyLoc = lastCatchBody->getLocStart();
const char *bodyBuf = SM->getCharacterData(bodyLoc);
const char *rParenBuf = SM->getCharacterData(rParenLoc);
@@ -1904,8 +1937,6 @@ Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
} else {
assert(false && "@catch rewrite bug");
}
- // make sure all the catch bodies get rewritten!
- catchList = catchList->getNextCatchStmt();
}
// Complete the catch list...
if (lastCatchBody) {
@@ -2054,10 +2085,10 @@ CallExpr *RewriteObjC::SynthesizeCallToFunctionDecl(
// Now, we cast the reference to a pointer to the objc_msgSend type.
QualType pToFunc = Context->getPointerType(msgSendType);
- ImplicitCastExpr *ICE = new (Context) ImplicitCastExpr(pToFunc,
- CastExpr::CK_Unknown,
- DRE,
- /*isLvalue=*/false);
+ ImplicitCastExpr *ICE =
+ new (Context) ImplicitCastExpr(pToFunc, CastExpr::CK_Unknown,
+ DRE, CXXBaseSpecifierArray(),
+ /*isLvalue=*/false);
const FunctionType *FT = msgSendType->getAs<FunctionType>();
@@ -2267,7 +2298,8 @@ void RewriteObjC::SynthSelGetUidFunctionDecl() {
SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
SelGetUidIdent, getFuncType, 0,
- FunctionDecl::Extern, false);
+ FunctionDecl::Extern,
+ FunctionDecl::None, false);
}
void RewriteObjC::RewriteFunctionDecl(FunctionDecl *FD) {
@@ -2364,7 +2396,8 @@ void RewriteObjC::SynthSuperContructorFunctionDecl() {
SuperContructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
msgSendIdent, msgSendType, 0,
- FunctionDecl::Extern, false);
+ FunctionDecl::Extern,
+ FunctionDecl::None, false);
}
// SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...);
@@ -2385,7 +2418,8 @@ void RewriteObjC::SynthMsgSendFunctionDecl() {
MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
msgSendIdent, msgSendType, 0,
- FunctionDecl::Extern, false);
+ FunctionDecl::Extern,
+ FunctionDecl::None, false);
}
// SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(struct objc_super *, SEL op, ...);
@@ -2409,7 +2443,8 @@ void RewriteObjC::SynthMsgSendSuperFunctionDecl() {
MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
msgSendIdent, msgSendType, 0,
- FunctionDecl::Extern, false);
+ FunctionDecl::Extern,
+ FunctionDecl::None, false);
}
// SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...);
@@ -2430,7 +2465,8 @@ void RewriteObjC::SynthMsgSendStretFunctionDecl() {
MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
msgSendIdent, msgSendType, 0,
- FunctionDecl::Extern, false);
+ FunctionDecl::Extern,
+ FunctionDecl::None, false);
}
// SynthMsgSendSuperStretFunctionDecl -
@@ -2456,7 +2492,8 @@ void RewriteObjC::SynthMsgSendSuperStretFunctionDecl() {
MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
msgSendIdent, msgSendType, 0,
- FunctionDecl::Extern, false);
+ FunctionDecl::Extern,
+ FunctionDecl::None, false);
}
// SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...);
@@ -2477,7 +2514,8 @@ void RewriteObjC::SynthMsgSendFpretFunctionDecl() {
MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
msgSendIdent, msgSendType, 0,
- FunctionDecl::Extern, false);
+ FunctionDecl::Extern,
+ FunctionDecl::None, false);
}
// SynthGetClassFunctionDecl - id objc_getClass(const char *name);
@@ -2493,7 +2531,8 @@ void RewriteObjC::SynthGetClassFunctionDecl() {
GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
getClassIdent, getClassType, 0,
- FunctionDecl::Extern, false);
+ FunctionDecl::Extern,
+ FunctionDecl::None, false);
}
// SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls);
@@ -2508,9 +2547,12 @@ void RewriteObjC::SynthGetSuperClassFunctionDecl() {
false, false, 0, 0,
FunctionType::ExtInfo());
GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
- SourceLocation(),
- getSuperClassIdent, getClassType, 0,
- FunctionDecl::Extern, false);
+ SourceLocation(),
+ getSuperClassIdent,
+ getClassType, 0,
+ FunctionDecl::Extern,
+ FunctionDecl::None,
+ false);
}
// SynthGetMetaClassFunctionDecl - id objc_getClass(const char *name);
@@ -2526,7 +2568,8 @@ void RewriteObjC::SynthGetMetaClassFunctionDecl() {
GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
SourceLocation(),
getClassIdent, getClassType, 0,
- FunctionDecl::Extern, false);
+ FunctionDecl::Extern,
+ FunctionDecl::None, false);
}
Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
@@ -2560,7 +2603,7 @@ Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
&Context->Idents.get(S), strType, 0,
- VarDecl::Static);
+ VarDecl::Static, VarDecl::None);
DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, strType, SourceLocation());
Expr *Unop = new (Context) UnaryOperator(DRE, UnaryOperator::AddrOf,
Context->getPointerType(DRE->getType()),
@@ -2665,7 +2708,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
FunctionDecl *MsgSendStretFlavor = 0;
if (ObjCMethodDecl *mDecl = Exp->getMethodDecl()) {
QualType resultType = mDecl->getResultType();
- if (resultType->isStructureType() || resultType->isUnionType())
+ if (resultType->isRecordType())
MsgSendStretFlavor = MsgSendStretFunctionDecl;
else if (resultType->isRealFloatingType())
MsgSendFlavor = MsgSendFpretFunctionDecl;
@@ -2673,203 +2716,211 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
// Synthesize a call to objc_msgSend().
llvm::SmallVector<Expr*, 8> MsgExprs;
- IdentifierInfo *clsName = Exp->getClassName();
-
- // Derive/push the receiver/selector, 2 implicit arguments to objc_msgSend().
- if (clsName) { // class message.
- // FIXME: We need to fix Sema (and the AST for ObjCMessageExpr) to handle
- // the 'super' idiom within a class method.
- if (clsName->getName() == "super") {
- MsgSendFlavor = MsgSendSuperFunctionDecl;
- if (MsgSendStretFlavor)
- MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
- assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
-
- ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
-
- llvm::SmallVector<Expr*, 4> InitExprs;
-
- // set the receiver to self, the first argument to all methods.
- InitExprs.push_back(
- NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
- CastExpr::CK_Unknown,
- new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
- Context->getObjCIdType(),
- SourceLocation()))
- ); // set the 'receiver'.
-
- // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
- llvm::SmallVector<Expr*, 8> ClsExprs;
- QualType argType = Context->getPointerType(Context->CharTy);
- ClsExprs.push_back(StringLiteral::Create(*Context,
- ClassDecl->getIdentifier()->getNameStart(),
- ClassDecl->getIdentifier()->getLength(),
- false, argType, SourceLocation()));
- CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
- &ClsExprs[0],
- ClsExprs.size(),
- StartLoc,
- EndLoc);
- // (Class)objc_getClass("CurrentClass")
- CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
- Context->getObjCClassType(),
- CastExpr::CK_Unknown, Cls);
- ClsExprs.clear();
- ClsExprs.push_back(ArgExpr);
- Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
- &ClsExprs[0], ClsExprs.size(),
- StartLoc, EndLoc);
-
- // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
- // To turn off a warning, type-cast to 'id'
- InitExprs.push_back( // set 'super class', using class_getSuperclass().
- NoTypeInfoCStyleCastExpr(Context,
- Context->getObjCIdType(),
- CastExpr::CK_Unknown, Cls));
- // struct objc_super
- QualType superType = getSuperStructType();
- Expr *SuperRep;
-
- if (LangOpts.Microsoft) {
- SynthSuperContructorFunctionDecl();
- // Simulate a contructor call...
- DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
- superType, SourceLocation());
- SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
- InitExprs.size(),
- superType, SourceLocation());
- // The code for super is a little tricky to prevent collision with
- // the structure definition in the header. The rewriter has it's own
- // internal definition (__rw_objc_super) that is uses. This is why
- // we need the cast below. For example:
- // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
- //
- SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
- Context->getPointerType(SuperRep->getType()),
- SourceLocation());
- SuperRep = NoTypeInfoCStyleCastExpr(Context,
- Context->getPointerType(superType),
- CastExpr::CK_Unknown, SuperRep);
- } else {
- // (struct objc_super) { <exprs from above> }
- InitListExpr *ILE = new (Context) InitListExpr(SourceLocation(),
- &InitExprs[0], InitExprs.size(),
- SourceLocation());
- TypeSourceInfo *superTInfo
- = Context->getTrivialTypeSourceInfo(superType);
- SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
- superType, ILE, false);
- // struct objc_super *
- SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
- Context->getPointerType(SuperRep->getType()),
- SourceLocation());
- }
- MsgExprs.push_back(SuperRep);
+ switch (Exp->getReceiverKind()) {
+ case ObjCMessageExpr::SuperClass: {
+ MsgSendFlavor = MsgSendSuperFunctionDecl;
+ if (MsgSendStretFlavor)
+ MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
+ assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
+
+ ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
+
+ llvm::SmallVector<Expr*, 4> InitExprs;
+
+ // set the receiver to self, the first argument to all methods.
+ InitExprs.push_back(
+ NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+ CastExpr::CK_Unknown,
+ new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+ Context->getObjCIdType(),
+ SourceLocation()))
+ ); // set the 'receiver'.
+
+ // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+ llvm::SmallVector<Expr*, 8> ClsExprs;
+ QualType argType = Context->getPointerType(Context->CharTy);
+ ClsExprs.push_back(StringLiteral::Create(*Context,
+ ClassDecl->getIdentifier()->getNameStart(),
+ ClassDecl->getIdentifier()->getLength(),
+ false, argType, SourceLocation()));
+ CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
+ &ClsExprs[0],
+ ClsExprs.size(),
+ StartLoc,
+ EndLoc);
+ // (Class)objc_getClass("CurrentClass")
+ CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
+ Context->getObjCClassType(),
+ CastExpr::CK_Unknown, Cls);
+ ClsExprs.clear();
+ ClsExprs.push_back(ArgExpr);
+ Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
+ &ClsExprs[0], ClsExprs.size(),
+ StartLoc, EndLoc);
+
+ // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+ // To turn off a warning, type-cast to 'id'
+ InitExprs.push_back( // set 'super class', using class_getSuperclass().
+ NoTypeInfoCStyleCastExpr(Context,
+ Context->getObjCIdType(),
+ CastExpr::CK_Unknown, Cls));
+ // struct objc_super
+ QualType superType = getSuperStructType();
+ Expr *SuperRep;
+
+ if (LangOpts.Microsoft) {
+ SynthSuperContructorFunctionDecl();
+ // Simulate a contructor call...
+ DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
+ superType, SourceLocation());
+ SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
+ InitExprs.size(),
+ superType, SourceLocation());
+ // The code for super is a little tricky to prevent collision with
+ // the structure definition in the header. The rewriter has it's own
+ // internal definition (__rw_objc_super) that is uses. This is why
+ // we need the cast below. For example:
+ // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
+ //
+ SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
+ Context->getPointerType(SuperRep->getType()),
+ SourceLocation());
+ SuperRep = NoTypeInfoCStyleCastExpr(Context,
+ Context->getPointerType(superType),
+ CastExpr::CK_Unknown, SuperRep);
} else {
- llvm::SmallVector<Expr*, 8> ClsExprs;
- QualType argType = Context->getPointerType(Context->CharTy);
- ClsExprs.push_back(StringLiteral::Create(*Context,
- clsName->getNameStart(),
- clsName->getLength(),
- false, argType,
- SourceLocation()));
- CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
- &ClsExprs[0],
- ClsExprs.size(),
- StartLoc, EndLoc);
- MsgExprs.push_back(Cls);
+ // (struct objc_super) { <exprs from above> }
+ InitListExpr *ILE =
+ new (Context) InitListExpr(*Context, SourceLocation(),
+ &InitExprs[0], InitExprs.size(),
+ SourceLocation());
+ TypeSourceInfo *superTInfo
+ = Context->getTrivialTypeSourceInfo(superType);
+ SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
+ superType, ILE, false);
+ // struct objc_super *
+ SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
+ Context->getPointerType(SuperRep->getType()),
+ SourceLocation());
}
- } else { // instance message.
- Expr *recExpr = Exp->getReceiver();
-
- if (isSuperReceiver(recExpr)) {
- MsgSendFlavor = MsgSendSuperFunctionDecl;
- if (MsgSendStretFlavor)
- MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
- assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
- ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
- llvm::SmallVector<Expr*, 4> InitExprs;
-
- InitExprs.push_back(
- NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
- CastExpr::CK_Unknown,
- new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
- Context->getObjCIdType(),
- SourceLocation()))
- ); // set the 'receiver'.
-
- // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
- llvm::SmallVector<Expr*, 8> ClsExprs;
- QualType argType = Context->getPointerType(Context->CharTy);
- ClsExprs.push_back(StringLiteral::Create(*Context,
- ClassDecl->getIdentifier()->getNameStart(),
- ClassDecl->getIdentifier()->getLength(),
- false, argType, SourceLocation()));
- CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
- &ClsExprs[0],
- ClsExprs.size(),
- StartLoc, EndLoc);
- // (Class)objc_getClass("CurrentClass")
- CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
- Context->getObjCClassType(),
- CastExpr::CK_Unknown, Cls);
- ClsExprs.clear();
- ClsExprs.push_back(ArgExpr);
- Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
- &ClsExprs[0], ClsExprs.size(),
- StartLoc, EndLoc);
-
- // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
- // To turn off a warning, type-cast to 'id'
- InitExprs.push_back(
- // set 'super class', using class_getSuperclass().
- NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
- CastExpr::CK_Unknown, Cls));
- // struct objc_super
- QualType superType = getSuperStructType();
- Expr *SuperRep;
-
- if (LangOpts.Microsoft) {
- SynthSuperContructorFunctionDecl();
- // Simulate a contructor call...
- DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
- superType, SourceLocation());
- SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
- InitExprs.size(),
- superType, SourceLocation());
- // The code for super is a little tricky to prevent collision with
- // the structure definition in the header. The rewriter has it's own
- // internal definition (__rw_objc_super) that is uses. This is why
- // we need the cast below. For example:
- // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
- //
- SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
- Context->getPointerType(SuperRep->getType()),
- SourceLocation());
- SuperRep = NoTypeInfoCStyleCastExpr(Context,
- Context->getPointerType(superType),
- CastExpr::CK_Unknown, SuperRep);
- } else {
- // (struct objc_super) { <exprs from above> }
- InitListExpr *ILE = new (Context) InitListExpr(SourceLocation(),
- &InitExprs[0], InitExprs.size(),
- SourceLocation());
- TypeSourceInfo *superTInfo
- = Context->getTrivialTypeSourceInfo(superType);
- SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
- superType, ILE, false);
- }
- MsgExprs.push_back(SuperRep);
+ MsgExprs.push_back(SuperRep);
+ break;
+ }
+
+ case ObjCMessageExpr::Class: {
+ llvm::SmallVector<Expr*, 8> ClsExprs;
+ QualType argType = Context->getPointerType(Context->CharTy);
+ ObjCInterfaceDecl *Class
+ = Exp->getClassReceiver()->getAs<ObjCInterfaceType>()->getDecl();
+ IdentifierInfo *clsName = Class->getIdentifier();
+ ClsExprs.push_back(StringLiteral::Create(*Context,
+ clsName->getNameStart(),
+ clsName->getLength(),
+ false, argType,
+ SourceLocation()));
+ CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+ &ClsExprs[0],
+ ClsExprs.size(),
+ StartLoc, EndLoc);
+ MsgExprs.push_back(Cls);
+ break;
+ }
+
+ case ObjCMessageExpr::SuperInstance:{
+ MsgSendFlavor = MsgSendSuperFunctionDecl;
+ if (MsgSendStretFlavor)
+ MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
+ assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
+ ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
+ llvm::SmallVector<Expr*, 4> InitExprs;
+
+ InitExprs.push_back(
+ NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+ CastExpr::CK_Unknown,
+ new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+ Context->getObjCIdType(),
+ SourceLocation()))
+ ); // set the 'receiver'.
+
+ // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+ llvm::SmallVector<Expr*, 8> ClsExprs;
+ QualType argType = Context->getPointerType(Context->CharTy);
+ ClsExprs.push_back(StringLiteral::Create(*Context,
+ ClassDecl->getIdentifier()->getNameStart(),
+ ClassDecl->getIdentifier()->getLength(),
+ false, argType, SourceLocation()));
+ CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+ &ClsExprs[0],
+ ClsExprs.size(),
+ StartLoc, EndLoc);
+ // (Class)objc_getClass("CurrentClass")
+ CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
+ Context->getObjCClassType(),
+ CastExpr::CK_Unknown, Cls);
+ ClsExprs.clear();
+ ClsExprs.push_back(ArgExpr);
+ Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
+ &ClsExprs[0], ClsExprs.size(),
+ StartLoc, EndLoc);
+
+ // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+ // To turn off a warning, type-cast to 'id'
+ InitExprs.push_back(
+ // set 'super class', using class_getSuperclass().
+ NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+ CastExpr::CK_Unknown, Cls));
+ // struct objc_super
+ QualType superType = getSuperStructType();
+ Expr *SuperRep;
+
+ if (LangOpts.Microsoft) {
+ SynthSuperContructorFunctionDecl();
+ // Simulate a contructor call...
+ DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
+ superType, SourceLocation());
+ SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
+ InitExprs.size(),
+ superType, SourceLocation());
+ // The code for super is a little tricky to prevent collision with
+ // the structure definition in the header. The rewriter has it's own
+ // internal definition (__rw_objc_super) that is uses. This is why
+ // we need the cast below. For example:
+ // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
+ //
+ SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
+ Context->getPointerType(SuperRep->getType()),
+ SourceLocation());
+ SuperRep = NoTypeInfoCStyleCastExpr(Context,
+ Context->getPointerType(superType),
+ CastExpr::CK_Unknown, SuperRep);
} else {
- // Remove all type-casts because it may contain objc-style types; e.g.
- // Foo<Proto> *.
- while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr))
- recExpr = CE->getSubExpr();
- recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
- CastExpr::CK_Unknown, recExpr);
- MsgExprs.push_back(recExpr);
+ // (struct objc_super) { <exprs from above> }
+ InitListExpr *ILE =
+ new (Context) InitListExpr(*Context, SourceLocation(),
+ &InitExprs[0], InitExprs.size(),
+ SourceLocation());
+ TypeSourceInfo *superTInfo
+ = Context->getTrivialTypeSourceInfo(superType);
+ SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
+ superType, ILE, false);
}
+ MsgExprs.push_back(SuperRep);
+ break;
+ }
+
+ case ObjCMessageExpr::Instance: {
+ // Remove all type-casts because it may contain objc-style types; e.g.
+ // Foo<Proto> *.
+ Expr *recExpr = Exp->getInstanceReceiver();
+ while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr))
+ recExpr = CE->getSubExpr();
+ recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+ CastExpr::CK_Unknown, recExpr);
+ MsgExprs.push_back(recExpr);
+ break;
}
+ }
+
// Create a call to sel_registerName("selName"), it will be the 2nd argument.
llvm::SmallVector<Expr*, 8> SelExprs;
QualType argType = Context->getPointerType(Context->CharTy);
@@ -3070,7 +3121,8 @@ Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
std::string Name = "_OBJC_PROTOCOL_" + Exp->getProtocol()->getNameAsString();
IdentifierInfo *ID = &Context->Idents.get(Name);
VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
- ID, getProtocolType(), 0, VarDecl::Extern);
+ ID, getProtocolType(), 0,
+ VarDecl::Extern, VarDecl::None);
DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, getProtocolType(), SourceLocation());
Expr *DerefExpr = new (Context) UnaryOperator(DRE, UnaryOperator::AddrOf,
Context->getPointerType(DRE->getType()),
@@ -5066,8 +5118,8 @@ FunctionDecl *RewriteObjC::SynthBlockInitFunctionDecl(const char *name) {
IdentifierInfo *ID = &Context->Idents.get(name);
QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy);
return FunctionDecl::Create(*Context, TUDecl,SourceLocation(),
- ID, FType, 0, FunctionDecl::Extern, false,
- false);
+ ID, FType, 0, FunctionDecl::Extern,
+ FunctionDecl::None, false, false);
}
Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
@@ -5147,7 +5199,7 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
&Context->Idents.get(DescData.c_str()),
Context->VoidPtrTy, 0,
- VarDecl::Static);
+ VarDecl::Static, VarDecl::None);
UnaryOperator *DescRefExpr = new (Context) UnaryOperator(
new (Context) DeclRefExpr(NewVD,
Context->VoidPtrTy, SourceLocation()),
diff --git a/lib/Frontend/StmtXML.cpp b/lib/Frontend/StmtXML.cpp
index ce474d365390..21dc0ba0a188 100644
--- a/lib/Frontend/StmtXML.cpp
+++ b/lib/Frontend/StmtXML.cpp
@@ -125,6 +125,7 @@ namespace {
void VisitFloatingLiteral(FloatingLiteral *Node);
void VisitStringLiteral(StringLiteral *Str);
void VisitUnaryOperator(UnaryOperator *Node);
+ void VisitOffsetOfExpr(OffsetOfExpr *Node);
void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node);
void VisitMemberExpr(MemberExpr *Node);
void VisitExtVectorElementExpr(ExtVectorElementExpr *Node);
@@ -308,6 +309,10 @@ void StmtXML::VisitUnaryOperator(UnaryOperator *Node) {
Doc.addAttribute("op_code", getOpcodeStr(Node->getOpcode()));
}
+void StmtXML::OffsetOfExpr(OffsetOfExpr *Node) {
+ DumpExpr(Node);
+}
+
void StmtXML::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
DumpExpr(Node);
Doc.addAttribute("is_sizeof", Node->isSizeOf() ? "sizeof" : "alignof");
diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp
index 4e91f8d4c221..28bb17ac3efa 100644
--- a/lib/Frontend/TextDiagnosticPrinter.cpp
+++ b/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -148,9 +148,16 @@ static void SelectInterestingSourceRegion(std::string &SourceLine,
std::string &FixItInsertionLine,
unsigned EndOfCaretToken,
unsigned Columns) {
- if (CaretLine.size() > SourceLine.size())
- SourceLine.resize(CaretLine.size(), ' ');
-
+ unsigned MaxSize = std::max(SourceLine.size(),
+ std::max(CaretLine.size(),
+ FixItInsertionLine.size()));
+ if (MaxSize > SourceLine.size())
+ SourceLine.resize(MaxSize, ' ');
+ if (MaxSize > CaretLine.size())
+ CaretLine.resize(MaxSize, ' ');
+ if (!FixItInsertionLine.empty() && MaxSize > FixItInsertionLine.size())
+ FixItInsertionLine.resize(MaxSize, ' ');
+
// Find the slice that we need to display the full caret line
// correctly.
unsigned CaretStart = 0, CaretEnd = CaretLine.size();
@@ -275,7 +282,7 @@ static void SelectInterestingSourceRegion(std::string &SourceLine,
void TextDiagnosticPrinter::EmitCaretDiagnostic(SourceLocation Loc,
SourceRange *Ranges,
unsigned NumRanges,
- SourceManager &SM,
+ const SourceManager &SM,
const FixItHint *Hints,
unsigned NumHints,
unsigned Columns) {
@@ -796,8 +803,13 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level,
OutStr += " [-W";
OutStr += Opt;
OutStr += ']';
- } else if (Diagnostic::isBuiltinExtensionDiag(Info.getID())) {
- OutStr += " [-pedantic]";
+ } else {
+ // If the diagnostic is an extension diagnostic and not enabled by default
+ // then it must have been turned on with -pedantic.
+ bool EnabledByDefault;
+ if (Diagnostic::isBuiltinExtensionDiag(Info.getID(), EnabledByDefault) &&
+ !EnabledByDefault)
+ OutStr += " [-pedantic]";
}
}
diff --git a/lib/Frontend/VerifyDiagnosticsClient.cpp b/lib/Frontend/VerifyDiagnosticsClient.cpp
index 99ec910be0af..ae36481444da 100644
--- a/lib/Frontend/VerifyDiagnosticsClient.cpp
+++ b/lib/Frontend/VerifyDiagnosticsClient.cpp
@@ -16,6 +16,7 @@
#include "clang/Frontend/TextDiagnosticBuffer.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Regex.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
@@ -71,97 +72,267 @@ bool VerifyDiagnosticsClient::HadErrors() {
typedef TextDiagnosticBuffer::DiagList DiagList;
typedef TextDiagnosticBuffer::const_iterator const_diag_iterator;
-/// FindDiagnostics - Go through the comment and see if it indicates expected
-/// diagnostics. If so, then put them in a diagnostic list.
+namespace {
+
+/// Directive - Abstract class representing a parsed verify directive.
///
-static void FindDiagnostics(const char *CommentStart, unsigned CommentLen,
- DiagList &ExpectedDiags,
- Preprocessor &PP, SourceLocation Pos,
- const char *ExpectedStr) {
- const char *CommentEnd = CommentStart+CommentLen;
- unsigned ExpectedStrLen = strlen(ExpectedStr);
-
- // Find all expected-foo diagnostics in the string and add them to
- // ExpectedDiags.
- while (CommentStart != CommentEnd) {
- CommentStart = std::find(CommentStart, CommentEnd, 'e');
- if (unsigned(CommentEnd-CommentStart) < ExpectedStrLen) return;
-
- // If this isn't expected-foo, ignore it.
- if (memcmp(CommentStart, ExpectedStr, ExpectedStrLen)) {
- ++CommentStart;
- continue;
- }
+class Directive {
+public:
+ static Directive* Create(bool RegexKind, const SourceLocation &Location,
+ const std::string &Text, unsigned Count);
+public:
+ SourceLocation Location;
+ const std::string Text;
+ unsigned Count;
+
+ virtual ~Directive() { }
+
+ // Returns true if directive text is valid.
+ // Otherwise returns false and populates E.
+ virtual bool isValid(std::string &Error) = 0;
+
+ // Returns true on match.
+ virtual bool Match(const std::string &S) = 0;
+
+protected:
+ Directive(const SourceLocation &Location, const std::string &Text,
+ unsigned Count)
+ : Location(Location), Text(Text), Count(Count) { }
+
+private:
+ Directive(const Directive&); // DO NOT IMPLEMENT
+ void operator=(const Directive&); // DO NOT IMPLEMENT
+};
+
+/// StandardDirective - Directive with string matching.
+///
+class StandardDirective : public Directive {
+public:
+ StandardDirective(const SourceLocation &Location, const std::string &Text,
+ unsigned Count)
+ : Directive(Location, Text, Count) { }
+
+ virtual bool isValid(std::string &Error) {
+ // all strings are considered valid; even empty ones
+ return true;
+ }
+
+ virtual bool Match(const std::string &S) {
+ return S.find(Text) != std::string::npos ||
+ Text.find(S) != std::string::npos;
+ }
+};
+
+/// RegexDirective - Directive with regular-expression matching.
+///
+class RegexDirective : public Directive {
+public:
+ RegexDirective(const SourceLocation &Location, const std::string &Text,
+ unsigned Count)
+ : Directive(Location, Text, Count), Regex(Text) { }
+
+ virtual bool isValid(std::string &Error) {
+ if (Regex.isValid(Error))
+ return true;
+ return false;
+ }
+
+ virtual bool Match(const std::string &S) {
+ return Regex.match(S);
+ }
- CommentStart += ExpectedStrLen;
-
- // Skip whitespace.
- while (CommentStart != CommentEnd &&
- isspace(CommentStart[0]))
- ++CommentStart;
-
- // Default, if we find the '{' now, is 1 time.
- int Times = 1;
- int Temp = 0;
- // In extended syntax, there could be a digit now.
- while (CommentStart != CommentEnd &&
- CommentStart[0] >= '0' && CommentStart[0] <= '9') {
- Temp *= 10;
- Temp += CommentStart[0] - '0';
- ++CommentStart;
+private:
+ llvm::Regex Regex;
+};
+
+typedef std::vector<Directive*> DirectiveList;
+
+/// ExpectedData - owns directive objects and deletes on destructor.
+///
+struct ExpectedData {
+ DirectiveList Errors;
+ DirectiveList Warnings;
+ DirectiveList Notes;
+
+ ~ExpectedData() {
+ DirectiveList* Lists[] = { &Errors, &Warnings, &Notes, 0 };
+ for (DirectiveList **PL = Lists; *PL; ++PL) {
+ DirectiveList * const L = *PL;
+ for (DirectiveList::iterator I = L->begin(), E = L->end(); I != E; ++I)
+ delete *I;
}
- if (Temp > 0)
- Times = Temp;
-
- // Skip whitespace again.
- while (CommentStart != CommentEnd &&
- isspace(CommentStart[0]))
- ++CommentStart;
-
- // We should have a {{ now.
- if (CommentEnd-CommentStart < 2 ||
- CommentStart[0] != '{' || CommentStart[1] != '{') {
- if (std::find(CommentStart, CommentEnd, '{') != CommentEnd)
- PP.Diag(Pos, diag::err_verify_bogus_characters);
- else
- PP.Diag(Pos, diag::err_verify_missing_start);
- return;
+ }
+};
+
+class ParseHelper
+{
+public:
+ ParseHelper(const char *Begin, const char *End)
+ : Begin(Begin), End(End), C(Begin), P(Begin), PEnd(NULL) { }
+
+ // Return true if string literal is next.
+ bool Next(const std::string &S) {
+ std::string::size_type LEN = S.length();
+ P = C;
+ PEnd = C + LEN;
+ if (PEnd > End)
+ return false;
+ return !memcmp(P, S.c_str(), LEN);
+ }
+
+ // Return true if number is next.
+ // Output N only if number is next.
+ bool Next(unsigned &N) {
+ unsigned TMP = 0;
+ P = C;
+ for (; P < End && P[0] >= '0' && P[0] <= '9'; ++P) {
+ TMP *= 10;
+ TMP += P[0] - '0';
}
- CommentStart += 2;
-
- // Find the }}.
- const char *ExpectedEnd = CommentStart;
- while (1) {
- ExpectedEnd = std::find(ExpectedEnd, CommentEnd, '}');
- if (CommentEnd-ExpectedEnd < 2) {
- PP.Diag(Pos, diag::err_verify_missing_end);
- return;
- }
+ if (P == C)
+ return false;
+ PEnd = P;
+ N = TMP;
+ return true;
+ }
+
+ // Return true if string literal is found.
+ // When true, P marks begin-position of S in content.
+ bool Search(const std::string &S) {
+ P = std::search(C, End, S.begin(), S.end());
+ PEnd = P + S.length();
+ return P != End;
+ }
+
+ // Advance 1-past previous next/search.
+ // Behavior is undefined if previous next/search failed.
+ bool Advance() {
+ C = PEnd;
+ return C < End;
+ }
+
+ // Skip zero or more whitespace.
+ void SkipWhitespace() {
+ for (; C < End && isspace(*C); ++C)
+ ;
+ }
+
+ // Return true if EOF reached.
+ bool Done() {
+ return !(C < End);
+ }
+
+ const char * const Begin; // beginning of expected content
+ const char * const End; // end of expected content (1-past)
+ const char *C; // position of next char in content
+ const char *P;
+
+private:
+ const char *PEnd; // previous next/search subject end (1-past)
+};
+
+} // namespace anonymous
+
+/// ParseDirective - Go through the comment and see if it indicates expected
+/// diagnostics. If so, then put them in the appropriate directive list.
+///
+static void ParseDirective(const char *CommentStart, unsigned CommentLen,
+ ExpectedData &ED, Preprocessor &PP,
+ SourceLocation Pos) {
+ // A single comment may contain multiple directives.
+ for (ParseHelper PH(CommentStart, CommentStart+CommentLen); !PH.Done();) {
+ // search for token: expected
+ if (!PH.Search("expected"))
+ break;
+ PH.Advance();
+
+ // next token: -
+ if (!PH.Next("-"))
+ continue;
+ PH.Advance();
+
+ // next token: { error | warning | note }
+ DirectiveList* DL = NULL;
+ if (PH.Next("error"))
+ DL = &ED.Errors;
+ else if (PH.Next("warning"))
+ DL = &ED.Warnings;
+ else if (PH.Next("note"))
+ DL = &ED.Notes;
+ else
+ continue;
+ PH.Advance();
- if (ExpectedEnd[1] == '}')
- break;
+ // default directive kind
+ bool RegexKind = false;
+ const char* KindStr = "string";
- ++ExpectedEnd; // Skip over singular }'s
+ // next optional token: -
+ if (PH.Next("-re")) {
+ PH.Advance();
+ RegexKind = true;
+ KindStr = "regex";
}
- std::string Msg(CommentStart, ExpectedEnd);
- std::string::size_type FindPos;
- while ((FindPos = Msg.find("\\n")) != std::string::npos)
- Msg.replace(FindPos, 2, "\n");
- // Add is possibly multiple times.
- for (int i = 0; i < Times; ++i)
- ExpectedDiags.push_back(std::make_pair(Pos, Msg));
+ // skip optional whitespace
+ PH.SkipWhitespace();
+
+ // next optional token: positive integer
+ unsigned Count = 1;
+ if (PH.Next(Count))
+ PH.Advance();
+
+ // skip optional whitespace
+ PH.SkipWhitespace();
+
+ // next token: {{
+ if (!PH.Next("{{")) {
+ PP.Diag(Pos.getFileLocWithOffset(PH.C-PH.Begin),
+ diag::err_verify_missing_start) << KindStr;
+ continue;
+ }
+ PH.Advance();
+ const char* const ContentBegin = PH.C; // mark content begin
- CommentStart = ExpectedEnd;
+ // search for token: }}
+ if (!PH.Search("}}")) {
+ PP.Diag(Pos.getFileLocWithOffset(PH.C-PH.Begin),
+ diag::err_verify_missing_end) << KindStr;
+ continue;
+ }
+ const char* const ContentEnd = PH.P; // mark content end
+ PH.Advance();
+
+ // build directive text; convert \n to newlines
+ std::string Text;
+ llvm::StringRef NewlineStr = "\\n";
+ llvm::StringRef Content(ContentBegin, ContentEnd-ContentBegin);
+ size_t CPos = 0;
+ size_t FPos;
+ while ((FPos = Content.find(NewlineStr, CPos)) != llvm::StringRef::npos) {
+ Text += Content.substr(CPos, FPos-CPos);
+ Text += '\n';
+ CPos = FPos + NewlineStr.size();
+ }
+ if (Text.empty())
+ Text.assign(ContentBegin, ContentEnd);
+
+ // construct new directive
+ Directive *D = Directive::Create(RegexKind, Pos, Text, Count);
+ std::string Error;
+ if (D->isValid(Error))
+ DL->push_back(D);
+ else {
+ PP.Diag(Pos.getFileLocWithOffset(ContentBegin-PH.Begin),
+ diag::err_verify_invalid_content)
+ << KindStr << Error;
+ }
}
}
/// FindExpectedDiags - Lex the main source file to find all of the
// expected errors and warnings.
-static void FindExpectedDiags(Preprocessor &PP,
- DiagList &ExpectedErrors,
- DiagList &ExpectedWarnings,
- DiagList &ExpectedNotes) {
+static void FindExpectedDiags(Preprocessor &PP, ExpectedData &ED) {
// Create a raw lexer to pull all the comments out of the main file. We don't
// want to look in #include'd headers for expected-error strings.
SourceManager &SM = PP.getSourceManager();
@@ -185,17 +356,8 @@ static void FindExpectedDiags(Preprocessor &PP,
std::string Comment = PP.getSpelling(Tok);
if (Comment.empty()) continue;
- // Find all expected errors.
- FindDiagnostics(&Comment[0], Comment.size(), ExpectedErrors, PP,
- Tok.getLocation(), "expected-error");
-
- // Find all expected warnings.
- FindDiagnostics(&Comment[0], Comment.size(), ExpectedWarnings, PP,
- Tok.getLocation(), "expected-warning");
-
- // Find all expected notes.
- FindDiagnostics(&Comment[0], Comment.size(), ExpectedNotes, PP,
- Tok.getLocation(), "expected-note");
+ // Find all expected errors/warnings/notes.
+ ParseDirective(&Comment[0], Comment.size(), ED, PP, Tok.getLocation());
};
}
@@ -225,49 +387,68 @@ static unsigned PrintProblem(Diagnostic &Diags, SourceManager *SourceMgr,
return std::distance(diag_begin, diag_end);
}
-/// CompareDiagLists - Compare two diagnostic lists and return the difference
-/// between them.
+static unsigned PrintProblem(Diagnostic &Diags, SourceManager *SourceMgr,
+ DirectiveList &DL, const char *Kind,
+ bool Expected) {
+ if (DL.empty())
+ return 0;
+
+ llvm::SmallString<256> Fmt;
+ llvm::raw_svector_ostream OS(Fmt);
+ for (DirectiveList::iterator I = DL.begin(), E = DL.end(); I != E; ++I) {
+ Directive& D = **I;
+ if (D.Location.isInvalid() || !SourceMgr)
+ OS << "\n (frontend)";
+ else
+ OS << "\n Line " << SourceMgr->getInstantiationLineNumber(D.Location);
+ OS << ": " << D.Text;
+ }
+
+ Diags.Report(diag::err_verify_inconsistent_diags)
+ << Kind << !Expected << OS.str();
+ return DL.size();
+}
+
+/// CheckLists - Compare expected to seen diagnostic lists and return the
+/// the difference between them.
///
-static unsigned CompareDiagLists(Diagnostic &Diags,
- SourceManager &SourceMgr,
- const_diag_iterator d1_begin,
- const_diag_iterator d1_end,
- const_diag_iterator d2_begin,
- const_diag_iterator d2_end,
- const char *Label) {
- DiagList LeftOnly;
- DiagList Left(d1_begin, d1_end);
+static unsigned CheckLists(Diagnostic &Diags, SourceManager &SourceMgr,
+ const char *Label,
+ DirectiveList &Left,
+ const_diag_iterator d2_begin,
+ const_diag_iterator d2_end) {
+ DirectiveList LeftOnly;
DiagList Right(d2_begin, d2_end);
- for (const_diag_iterator I = Left.begin(), E = Left.end(); I != E; ++I) {
- unsigned LineNo1 = SourceMgr.getInstantiationLineNumber(I->first);
- const std::string &Diag1 = I->second;
+ for (DirectiveList::iterator I = Left.begin(), E = Left.end(); I != E; ++I) {
+ Directive& D = **I;
+ unsigned LineNo1 = SourceMgr.getInstantiationLineNumber(D.Location);
- DiagList::iterator II, IE;
- for (II = Right.begin(), IE = Right.end(); II != IE; ++II) {
- unsigned LineNo2 = SourceMgr.getInstantiationLineNumber(II->first);
- if (LineNo1 != LineNo2) continue;
+ for (unsigned i = 0; i < D.Count; ++i) {
+ DiagList::iterator II, IE;
+ for (II = Right.begin(), IE = Right.end(); II != IE; ++II) {
+ unsigned LineNo2 = SourceMgr.getInstantiationLineNumber(II->first);
+ if (LineNo1 != LineNo2)
+ continue;
- const std::string &Diag2 = II->second;
- if (Diag2.find(Diag1) != std::string::npos ||
- Diag1.find(Diag2) != std::string::npos) {
- break;
+ const std::string &RightText = II->second;
+ if (D.Match(RightText))
+ break;
+ }
+ if (II == IE) {
+ // Not found.
+ LeftOnly.push_back(*I);
+ } else {
+ // Found. The same cannot be found twice.
+ Right.erase(II);
}
- }
- if (II == IE) {
- // Not found.
- LeftOnly.push_back(*I);
- } else {
- // Found. The same cannot be found twice.
- Right.erase(II);
}
}
// Now all that's left in Right are those that were not matched.
- return (PrintProblem(Diags, &SourceMgr,
- LeftOnly.begin(), LeftOnly.end(), Label, true) +
- PrintProblem(Diags, &SourceMgr,
- Right.begin(), Right.end(), Label, false));
+ return (PrintProblem(Diags, &SourceMgr, LeftOnly, Label, true) +
+ PrintProblem(Diags, &SourceMgr, Right.begin(), Right.end(),
+ Label, false));
}
/// CheckResults - This compares the expected results to those that
@@ -276,9 +457,7 @@ static unsigned CompareDiagLists(Diagnostic &Diags,
///
static unsigned CheckResults(Diagnostic &Diags, SourceManager &SourceMgr,
const TextDiagnosticBuffer &Buffer,
- const DiagList &ExpectedErrors,
- const DiagList &ExpectedWarnings,
- const DiagList &ExpectedNotes) {
+ ExpectedData &ED) {
// We want to capture the delta between what was expected and what was
// seen.
//
@@ -287,31 +466,22 @@ static unsigned CheckResults(Diagnostic &Diags, SourceManager &SourceMgr,
unsigned NumProblems = 0;
// See if there are error mismatches.
- NumProblems += CompareDiagLists(Diags, SourceMgr,
- ExpectedErrors.begin(), ExpectedErrors.end(),
- Buffer.err_begin(), Buffer.err_end(),
- "error");
+ NumProblems += CheckLists(Diags, SourceMgr, "error", ED.Errors,
+ Buffer.err_begin(), Buffer.err_end());
// See if there are warning mismatches.
- NumProblems += CompareDiagLists(Diags, SourceMgr,
- ExpectedWarnings.begin(),
- ExpectedWarnings.end(),
- Buffer.warn_begin(), Buffer.warn_end(),
- "warning");
+ NumProblems += CheckLists(Diags, SourceMgr, "warning", ED.Warnings,
+ Buffer.warn_begin(), Buffer.warn_end());
// See if there are note mismatches.
- NumProblems += CompareDiagLists(Diags, SourceMgr,
- ExpectedNotes.begin(),
- ExpectedNotes.end(),
- Buffer.note_begin(), Buffer.note_end(),
- "note");
+ NumProblems += CheckLists(Diags, SourceMgr, "note", ED.Notes,
+ Buffer.note_begin(), Buffer.note_end());
return NumProblems;
}
-
void VerifyDiagnosticsClient::CheckDiagnostics() {
- DiagList ExpectedErrors, ExpectedWarnings, ExpectedNotes;
+ ExpectedData ED;
// Ensure any diagnostics go to the primary client.
DiagnosticClient *CurClient = Diags.getClient();
@@ -320,13 +490,11 @@ void VerifyDiagnosticsClient::CheckDiagnostics() {
// If we have a preprocessor, scan the source for expected diagnostic
// markers. If not then any diagnostics are unexpected.
if (CurrentPreprocessor) {
- FindExpectedDiags(*CurrentPreprocessor, ExpectedErrors, ExpectedWarnings,
- ExpectedNotes);
+ FindExpectedDiags(*CurrentPreprocessor, ED);
// Check that the expected diagnostics occurred.
NumErrors += CheckResults(Diags, CurrentPreprocessor->getSourceManager(),
- *Buffer,
- ExpectedErrors, ExpectedWarnings, ExpectedNotes);
+ *Buffer, ED);
} else {
NumErrors += (PrintProblem(Diags, 0,
Buffer->err_begin(), Buffer->err_end(),
@@ -344,3 +512,10 @@ void VerifyDiagnosticsClient::CheckDiagnostics() {
// Reset the buffer, we have processed all the diagnostics in it.
Buffer.reset(new TextDiagnosticBuffer());
}
+
+Directive* Directive::Create(bool RegexKind, const SourceLocation &Location,
+ const std::string &Text, unsigned Count) {
+ if (RegexKind)
+ return new RegexDirective(Location, Text, Count);
+ return new StandardDirective(Location, Text, Count);
+}
diff --git a/lib/Frontend/Warnings.cpp b/lib/Frontend/Warnings.cpp
index ea9635e79849..84c4f5d40faf 100644
--- a/lib/Frontend/Warnings.cpp
+++ b/lib/Frontend/Warnings.cpp
@@ -35,6 +35,12 @@ void clang::ProcessWarningOptions(Diagnostic &Diags,
const DiagnosticOptions &Opts) {
Diags.setSuppressSystemWarnings(true); // Default to -Wno-system-headers
Diags.setIgnoreAllWarnings(Opts.IgnoreWarnings);
+
+ // Handle -ferror-limit
+ if (Opts.ErrorLimit)
+ Diags.setErrorLimit(Opts.ErrorLimit);
+ if (Opts.TemplateBacktraceLimit)
+ Diags.setTemplateBacktraceLimit(Opts.TemplateBacktraceLimit);
// If -pedantic or -pedantic-errors was specified, then we want to map all
// extension diagnostics onto WARNING or ERROR unless the user has futz'd