aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTContext.cpp277
-rw-r--r--lib/AST/CFG.cpp61
-rw-r--r--lib/AST/Decl.cpp94
-rw-r--r--lib/AST/DeclBase.cpp114
-rw-r--r--lib/AST/DeclCXX.cpp63
-rw-r--r--lib/AST/DeclObjC.cpp103
-rw-r--r--lib/AST/DeclPrinter.cpp36
-rw-r--r--lib/AST/DeclTemplate.cpp27
-rw-r--r--lib/AST/Expr.cpp33
-rw-r--r--lib/AST/ExprCXX.cpp60
-rw-r--r--lib/AST/ExprConstant.cpp69
-rw-r--r--lib/AST/NestedNameSpecifier.cpp6
-rw-r--r--lib/AST/StmtDumper.cpp4
-rw-r--r--lib/AST/StmtPrinter.cpp24
-rw-r--r--lib/AST/TemplateName.cpp8
-rw-r--r--lib/AST/Type.cpp26
-rw-r--r--lib/Analysis/BasicStore.cpp104
-rw-r--r--lib/Analysis/BugReporter.cpp7
-rw-r--r--lib/Analysis/CFRefCount.cpp57
-rw-r--r--lib/Analysis/CheckDeadStores.cpp4
-rw-r--r--lib/Analysis/CheckObjCDealloc.cpp14
-rw-r--r--lib/Analysis/CheckObjCInstMethSignature.cpp8
-rw-r--r--lib/Analysis/CheckObjCUnusedIVars.cpp15
-rw-r--r--lib/Analysis/Environment.cpp15
-rw-r--r--lib/Analysis/GRExprEngine.cpp15
-rw-r--r--lib/Analysis/GRExprEngineInternalChecks.cpp2
-rw-r--r--lib/Analysis/GRState.cpp6
-rw-r--r--lib/Analysis/LiveVariables.cpp3
-rw-r--r--lib/Analysis/MemRegion.cpp46
-rw-r--r--lib/Analysis/RegionStore.cpp135
-rw-r--r--lib/Analysis/SVals.cpp7
-rw-r--r--lib/Analysis/Store.cpp6
-rw-r--r--lib/Basic/IdentifierTable.cpp2
-rw-r--r--lib/Basic/TargetInfo.cpp1
-rw-r--r--lib/Basic/Targets.cpp510
-rw-r--r--lib/CodeGen/CGBuiltin.cpp4
-rw-r--r--lib/CodeGen/CGCXX.cpp4
-rw-r--r--lib/CodeGen/CGCall.cpp27
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp9
-rw-r--r--lib/CodeGen/CGDecl.cpp12
-rw-r--r--lib/CodeGen/CGExpr.cpp4
-rw-r--r--lib/CodeGen/CGExprAgg.cpp8
-rw-r--r--lib/CodeGen/CGExprConstant.cpp8
-rw-r--r--lib/CodeGen/CGObjC.cpp6
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp41
-rw-r--r--lib/CodeGen/CGObjCMac.cpp67
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp4
-rw-r--r--lib/CodeGen/CodeGenModule.cpp105
-rw-r--r--lib/CodeGen/CodeGenModule.h3
-rw-r--r--lib/CodeGen/CodeGenTypes.cpp10
-rw-r--r--lib/CodeGen/Mangle.cpp34
-rw-r--r--lib/CodeGen/ModuleBuilder.cpp10
-rw-r--r--lib/CodeGen/TargetABIInfo.cpp24
-rw-r--r--lib/Driver/ArgList.cpp29
-rw-r--r--lib/Driver/Compilation.cpp43
-rw-r--r--lib/Driver/Driver.cpp50
-rw-r--r--lib/Driver/HostInfo.cpp57
-rw-r--r--lib/Driver/Job.cpp6
-rw-r--r--lib/Driver/ToolChains.cpp30
-rw-r--r--lib/Driver/ToolChains.h7
-rw-r--r--lib/Driver/Tools.cpp148
-rw-r--r--lib/Driver/Tools.h34
-rw-r--r--lib/Frontend/ASTConsumers.cpp15
-rw-r--r--lib/Frontend/AnalysisConsumer.cpp12
-rw-r--r--lib/Frontend/Backend.cpp11
-rw-r--r--lib/Frontend/DeclXML.cpp10
-rw-r--r--lib/Frontend/InitHeaderSearch.cpp8
-rw-r--r--lib/Frontend/InitPreprocessor.cpp9
-rw-r--r--lib/Frontend/PCHReader.cpp14
-rw-r--r--lib/Frontend/PCHReaderDecl.cpp2
-rw-r--r--lib/Frontend/PCHReaderStmt.cpp1
-rw-r--r--lib/Frontend/PCHWriter.cpp33
-rw-r--r--lib/Frontend/PCHWriterDecl.cpp6
-rw-r--r--lib/Frontend/PCHWriterStmt.cpp1
-rw-r--r--lib/Frontend/ResolveLocation.cpp8
-rw-r--r--lib/Frontend/RewriteBlocks.cpp33
-rw-r--r--lib/Frontend/RewriteObjC.cpp131
-rw-r--r--lib/Lex/Lexer.cpp9
-rw-r--r--lib/Lex/Pragma.cpp1
-rw-r--r--lib/Lex/Preprocessor.cpp23
-rw-r--r--lib/Parse/ParseDecl.cpp8
-rw-r--r--lib/Parse/ParseDeclCXX.cpp25
-rw-r--r--lib/Parse/ParseExpr.cpp15
-rw-r--r--lib/Parse/ParseExprCXX.cpp29
-rw-r--r--lib/Parse/Parser.cpp17
-rw-r--r--lib/Rewrite/Rewriter.cpp2
-rw-r--r--lib/Sema/JumpDiagnostics.cpp6
-rw-r--r--lib/Sema/Sema.cpp4
-rw-r--r--lib/Sema/Sema.h92
-rw-r--r--lib/Sema/SemaAttr.cpp2
-rw-r--r--lib/Sema/SemaChecking.cpp55
-rw-r--r--lib/Sema/SemaDecl.cpp93
-rw-r--r--lib/Sema/SemaDeclAttr.cpp111
-rw-r--r--lib/Sema/SemaDeclCXX.cpp168
-rw-r--r--lib/Sema/SemaDeclObjC.cpp155
-rw-r--r--lib/Sema/SemaExpr.cpp575
-rw-r--r--lib/Sema/SemaExprCXX.cpp8
-rw-r--r--lib/Sema/SemaExprObjC.cpp34
-rw-r--r--lib/Sema/SemaInherit.cpp4
-rw-r--r--lib/Sema/SemaInit.cpp29
-rw-r--r--lib/Sema/SemaLookup.cpp42
-rw-r--r--lib/Sema/SemaOverload.cpp72
-rw-r--r--lib/Sema/SemaStmt.cpp6
-rw-r--r--lib/Sema/SemaTemplate.cpp55
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp134
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp102
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp124
-rw-r--r--lib/Sema/SemaTemplateInstantiateExpr.cpp59
-rw-r--r--lib/Sema/SemaType.cpp79
109 files changed, 3307 insertions, 1871 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 12f75ae863a2..2877cc3b7fe7 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -37,12 +37,12 @@ ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM,
bool FreeMem, unsigned size_reserve) :
GlobalNestedNameSpecifier(0), CFConstantStringTypeDecl(0),
ObjCFastEnumerationStateTypeDecl(0), SourceMgr(SM), LangOpts(LOpts),
- FreeMemory(FreeMem), Target(t), Idents(idents), Selectors(sels),
- BuiltinInfo(builtins), ExternalSource(0) {
+ LoadedExternalComments(false), FreeMemory(FreeMem), Target(t),
+ Idents(idents), Selectors(sels),
+ BuiltinInfo(builtins), ExternalSource(0), PrintingPolicy(LOpts) {
if (size_reserve > 0) Types.reserve(size_reserve);
InitBuiltinTypes();
TUDecl = TranslationUnitDecl::Create(*this);
- PrintingPolicy.CPlusPlus = LangOpts.CPlusPlus;
}
ASTContext::~ASTContext() {
@@ -203,6 +203,207 @@ void ASTContext::InitBuiltinTypes() {
InitBuiltinType(NullPtrTy, BuiltinType::NullPtr);
}
+namespace {
+ class BeforeInTranslationUnit
+ : std::binary_function<SourceRange, SourceRange, bool> {
+ SourceManager *SourceMgr;
+
+ public:
+ explicit BeforeInTranslationUnit(SourceManager *SM) : SourceMgr(SM) { }
+
+ bool operator()(SourceRange X, SourceRange Y) {
+ return SourceMgr->isBeforeInTranslationUnit(X.getBegin(), Y.getBegin());
+ }
+ };
+}
+
+/// \brief Determine whether the given comment is a Doxygen-style comment.
+///
+/// \param Start the start of the comment text.
+///
+/// \param End the end of the comment text.
+///
+/// \param Member whether we want to check whether this is a member comment
+/// (which requires a < after the Doxygen-comment delimiter). Otherwise,
+/// we only return true when we find a non-member comment.
+static bool
+isDoxygenComment(SourceManager &SourceMgr, SourceRange Comment,
+ bool Member = false) {
+ const char *BufferStart
+ = SourceMgr.getBufferData(SourceMgr.getFileID(Comment.getBegin())).first;
+ const char *Start = BufferStart + SourceMgr.getFileOffset(Comment.getBegin());
+ const char* End = BufferStart + SourceMgr.getFileOffset(Comment.getEnd());
+
+ if (End - Start < 4)
+ return false;
+
+ assert(Start[0] == '/' && "Not a comment?");
+ if (Start[1] == '*' && !(Start[2] == '!' || Start[2] == '*'))
+ return false;
+ if (Start[1] == '/' && !(Start[2] == '!' || Start[2] == '/'))
+ return false;
+
+ return (Start[3] == '<') == Member;
+}
+
+/// \brief Retrieve the comment associated with the given declaration, if
+/// it has one.
+const char *ASTContext::getCommentForDecl(const Decl *D) {
+ if (!D)
+ return 0;
+
+ // Check whether we have cached a comment string for this declaration
+ // already.
+ llvm::DenseMap<const Decl *, std::string>::iterator Pos
+ = DeclComments.find(D);
+ if (Pos != DeclComments.end())
+ return Pos->second.c_str();
+
+ // If we have an external AST source and have not yet loaded comments from
+ // that source, do so now.
+ if (ExternalSource && !LoadedExternalComments) {
+ std::vector<SourceRange> LoadedComments;
+ ExternalSource->ReadComments(LoadedComments);
+
+ if (!LoadedComments.empty())
+ Comments.insert(Comments.begin(), LoadedComments.begin(),
+ LoadedComments.end());
+
+ LoadedExternalComments = true;
+ }
+
+ // If there are no comments anywhere, we won't find anything.
+ if (Comments.empty())
+ return 0;
+
+ // If the declaration doesn't map directly to a location in a file, we
+ // can't find the comment.
+ SourceLocation DeclStartLoc = D->getLocStart();
+ if (DeclStartLoc.isInvalid() || !DeclStartLoc.isFileID())
+ return 0;
+
+ // Find the comment that occurs just before this declaration.
+ std::vector<SourceRange>::iterator LastComment
+ = std::lower_bound(Comments.begin(), Comments.end(),
+ SourceRange(DeclStartLoc),
+ BeforeInTranslationUnit(&SourceMgr));
+
+ // Decompose the location for the start of the declaration and find the
+ // beginning of the file buffer.
+ std::pair<FileID, unsigned> DeclStartDecomp
+ = SourceMgr.getDecomposedLoc(DeclStartLoc);
+ const char *FileBufferStart
+ = SourceMgr.getBufferData(DeclStartDecomp.first).first;
+
+ // First check whether we have a comment for a member.
+ if (LastComment != Comments.end() &&
+ !isa<TagDecl>(D) && !isa<NamespaceDecl>(D) &&
+ isDoxygenComment(SourceMgr, *LastComment, true)) {
+ std::pair<FileID, unsigned> LastCommentEndDecomp
+ = SourceMgr.getDecomposedLoc(LastComment->getEnd());
+ if (DeclStartDecomp.first == LastCommentEndDecomp.first &&
+ SourceMgr.getLineNumber(DeclStartDecomp.first, DeclStartDecomp.second)
+ == SourceMgr.getLineNumber(LastCommentEndDecomp.first,
+ LastCommentEndDecomp.second)) {
+ // The Doxygen member comment comes after the declaration starts and
+ // is on the same line and in the same file as the declaration. This
+ // is the comment we want.
+ std::string &Result = DeclComments[D];
+ Result.append(FileBufferStart +
+ SourceMgr.getFileOffset(LastComment->getBegin()),
+ FileBufferStart + LastCommentEndDecomp.second + 1);
+ return Result.c_str();
+ }
+ }
+
+ if (LastComment == Comments.begin())
+ return 0;
+ --LastComment;
+
+ // Decompose the end of the comment.
+ std::pair<FileID, unsigned> LastCommentEndDecomp
+ = SourceMgr.getDecomposedLoc(LastComment->getEnd());
+
+ // If the comment and the declaration aren't in the same file, then they
+ // aren't related.
+ if (DeclStartDecomp.first != LastCommentEndDecomp.first)
+ return 0;
+
+ // Check that we actually have a Doxygen comment.
+ if (!isDoxygenComment(SourceMgr, *LastComment))
+ return 0;
+
+ // Compute the starting line for the declaration and for the end of the
+ // comment (this is expensive).
+ unsigned DeclStartLine
+ = SourceMgr.getLineNumber(DeclStartDecomp.first, DeclStartDecomp.second);
+ unsigned CommentEndLine
+ = SourceMgr.getLineNumber(LastCommentEndDecomp.first,
+ LastCommentEndDecomp.second);
+
+ // If the comment does not end on the line prior to the declaration, then
+ // the comment is not associated with the declaration at all.
+ if (CommentEndLine + 1 != DeclStartLine)
+ return 0;
+
+ // We have a comment, but there may be more comments on the previous lines.
+ // Keep looking so long as the comments are still Doxygen comments and are
+ // still adjacent.
+ unsigned ExpectedLine
+ = SourceMgr.getSpellingLineNumber(LastComment->getBegin()) - 1;
+ std::vector<SourceRange>::iterator FirstComment = LastComment;
+ while (FirstComment != Comments.begin()) {
+ // Look at the previous comment
+ --FirstComment;
+ std::pair<FileID, unsigned> Decomp
+ = SourceMgr.getDecomposedLoc(FirstComment->getEnd());
+
+ // If this previous comment is in a different file, we're done.
+ if (Decomp.first != DeclStartDecomp.first) {
+ ++FirstComment;
+ break;
+ }
+
+ // If this comment is not a Doxygen comment, we're done.
+ if (!isDoxygenComment(SourceMgr, *FirstComment)) {
+ ++FirstComment;
+ break;
+ }
+
+ // If the line number is not what we expected, we're done.
+ unsigned Line = SourceMgr.getLineNumber(Decomp.first, Decomp.second);
+ if (Line != ExpectedLine) {
+ ++FirstComment;
+ break;
+ }
+
+ // Set the next expected line number.
+ ExpectedLine
+ = SourceMgr.getSpellingLineNumber(FirstComment->getBegin()) - 1;
+ }
+
+ // The iterator range [FirstComment, LastComment] contains all of the
+ // BCPL comments that, together, are associated with this declaration.
+ // Form a single comment block string for this declaration that concatenates
+ // all of these comments.
+ std::string &Result = DeclComments[D];
+ while (FirstComment != LastComment) {
+ std::pair<FileID, unsigned> DecompStart
+ = SourceMgr.getDecomposedLoc(FirstComment->getBegin());
+ std::pair<FileID, unsigned> DecompEnd
+ = SourceMgr.getDecomposedLoc(FirstComment->getEnd());
+ Result.append(FileBufferStart + DecompStart.second,
+ FileBufferStart + DecompEnd.second + 1);
+ ++FirstComment;
+ }
+
+ // Append the last comment line.
+ Result.append(FileBufferStart +
+ SourceMgr.getFileOffset(LastComment->getBegin()),
+ FileBufferStart + LastCommentEndDecomp.second + 1);
+ return Result.c_str();
+}
+
//===----------------------------------------------------------------------===//
// Type Sizing and Analysis
//===----------------------------------------------------------------------===//
@@ -226,7 +427,7 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {
unsigned ASTContext::getDeclAlignInBytes(const Decl *D) {
unsigned Align = Target.getCharWidth();
- if (const AlignedAttr* AA = D->getAttr<AlignedAttr>(*this))
+ if (const AlignedAttr* AA = D->getAttr<AlignedAttr>())
Align = std::max(Align, AA->getAlignment());
if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
@@ -449,7 +650,7 @@ ASTContext::getTypeInfo(const Type *T) {
case Type::Typedef: {
const TypedefDecl *Typedef = cast<TypedefType>(T)->getDecl();
- if (const AlignedAttr *Aligned = Typedef->getAttr<AlignedAttr>(*this)) {
+ if (const AlignedAttr *Aligned = Typedef->getAttr<AlignedAttr>()) {
Align = Aligned->getAlignment();
Width = getTypeSize(Typedef->getUnderlyingType().getTypePtr());
} else
@@ -513,7 +714,7 @@ void ASTRecordLayout::LayoutField(const FieldDecl *FD, unsigned FieldNo,
// FIXME: Should this override struct packing? Probably we want to
// take the minimum?
- if (const PackedAttr *PA = FD->getAttr<PackedAttr>(Context))
+ if (const PackedAttr *PA = FD->getAttr<PackedAttr>())
FieldPacking = PA->getAlignment();
if (const Expr *BitWidthExpr = FD->getBitWidth()) {
@@ -533,7 +734,7 @@ void ASTRecordLayout::LayoutField(const FieldDecl *FD, unsigned FieldNo,
FieldAlign = FieldInfo.second;
if (FieldPacking)
FieldAlign = std::min(FieldAlign, FieldPacking);
- if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>(Context))
+ if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
FieldAlign = std::max(FieldAlign, AA->getAlignment());
// Check if we need to add padding to give the field the correct
@@ -573,7 +774,7 @@ void ASTRecordLayout::LayoutField(const FieldDecl *FD, unsigned FieldNo,
// is smaller than the specified packing?
if (FieldPacking)
FieldAlign = std::min(FieldAlign, std::max(8U, FieldPacking));
- if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>(Context))
+ if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>())
FieldAlign = std::max(FieldAlign, AA->getAlignment());
// Round up the current record size to the field's alignment boundary.
@@ -631,8 +832,8 @@ void ASTContext::ShallowCollectObjCIvars(const ObjCInterfaceDecl *OI,
void ASTContext::CollectProtocolSynthesizedIvars(const ObjCProtocolDecl *PD,
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
- for (ObjCContainerDecl::prop_iterator I = PD->prop_begin(*this),
- E = PD->prop_end(*this); I != E; ++I)
+ for (ObjCContainerDecl::prop_iterator I = PD->prop_begin(),
+ E = PD->prop_end(); I != E; ++I)
if (ObjCIvarDecl *Ivar = (*I)->getPropertyIvarDecl())
Ivars.push_back(Ivar);
@@ -647,8 +848,8 @@ void ASTContext::CollectProtocolSynthesizedIvars(const ObjCProtocolDecl *PD,
///
void ASTContext::CollectSynthesizedIvars(const ObjCInterfaceDecl *OI,
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars) {
- for (ObjCInterfaceDecl::prop_iterator I = OI->prop_begin(*this),
- E = OI->prop_end(*this); I != E; ++I) {
+ for (ObjCInterfaceDecl::prop_iterator I = OI->prop_begin(),
+ E = OI->prop_end(); I != E; ++I) {
if (ObjCIvarDecl *Ivar = (*I)->getPropertyIvarDecl())
Ivars.push_back(Ivar);
}
@@ -663,8 +864,8 @@ void ASTContext::CollectSynthesizedIvars(const ObjCInterfaceDecl *OI,
unsigned ASTContext::CountProtocolSynthesizedIvars(const ObjCProtocolDecl *PD) {
unsigned count = 0;
- for (ObjCContainerDecl::prop_iterator I = PD->prop_begin(*this),
- E = PD->prop_end(*this); I != E; ++I)
+ for (ObjCContainerDecl::prop_iterator I = PD->prop_begin(),
+ E = PD->prop_end(); I != E; ++I)
if ((*I)->getPropertyIvarDecl())
++count;
@@ -678,8 +879,8 @@ unsigned ASTContext::CountProtocolSynthesizedIvars(const ObjCProtocolDecl *PD) {
unsigned ASTContext::CountSynthesizedIvars(const ObjCInterfaceDecl *OI)
{
unsigned count = 0;
- for (ObjCInterfaceDecl::prop_iterator I = OI->prop_begin(*this),
- E = OI->prop_end(*this); I != E; ++I) {
+ for (ObjCInterfaceDecl::prop_iterator I = OI->prop_begin(),
+ E = OI->prop_end(); I != E; ++I) {
if ((*I)->getPropertyIvarDecl())
++count;
}
@@ -739,10 +940,10 @@ ASTContext::getObjCLayout(const ObjCInterfaceDecl *D,
}
unsigned StructPacking = 0;
- if (const PackedAttr *PA = D->getAttr<PackedAttr>(*this))
+ if (const PackedAttr *PA = D->getAttr<PackedAttr>())
StructPacking = PA->getAlignment();
- if (const AlignedAttr *AA = D->getAttr<AlignedAttr>(*this))
+ if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
NewEntry->SetAlignment(std::max(NewEntry->getAlignment(),
AA->getAlignment()));
@@ -786,23 +987,22 @@ const ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D) {
Entry = NewEntry;
// FIXME: Avoid linear walk through the fields, if possible.
- NewEntry->InitializeLayout(std::distance(D->field_begin(*this),
- D->field_end(*this)));
+ NewEntry->InitializeLayout(std::distance(D->field_begin(), D->field_end()));
bool IsUnion = D->isUnion();
unsigned StructPacking = 0;
- if (const PackedAttr *PA = D->getAttr<PackedAttr>(*this))
+ if (const PackedAttr *PA = D->getAttr<PackedAttr>())
StructPacking = PA->getAlignment();
- if (const AlignedAttr *AA = D->getAttr<AlignedAttr>(*this))
+ if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
NewEntry->SetAlignment(std::max(NewEntry->getAlignment(),
AA->getAlignment()));
// Layout each field, for now, just sequentially, respecting alignment. In
// the future, this will need to be tweakable by targets.
unsigned FieldIdx = 0;
- for (RecordDecl::field_iterator Field = D->field_begin(*this),
- FieldEnd = D->field_end(*this);
+ for (RecordDecl::field_iterator Field = D->field_begin(),
+ FieldEnd = D->field_end();
Field != FieldEnd; (void)++Field, ++FieldIdx)
NewEntry->LayoutField(*Field, FieldIdx, IsUnion, StructPacking, *this);
@@ -1636,13 +1836,6 @@ QualType ASTContext::getObjCQualifiedInterfaceType(ObjCInterfaceDecl *Decl,
return QualType(QType, 0);
}
-/// getObjCQualifiedIdType - Return an ObjCQualifiedIdType for the 'id' decl
-/// and the conforming protocol list.
-QualType ASTContext::getObjCQualifiedIdType(ObjCProtocolDecl **Protocols,
- unsigned NumProtocols) {
- return getObjCObjectPointerType(0, Protocols, NumProtocols);
-}
-
/// getTypeOfExprType - Unlike many "get<Type>" functions, we can't unique
/// TypeOfExprType AST's (since expression's are never shared). For example,
/// multiple declarations that refer to "typeof(x)" all contain different
@@ -1813,6 +2006,12 @@ Decl *ASTContext::getCanonicalDecl(Decl *D) {
return const_cast<FunctionDecl *>(Function);
}
+ if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D)) {
+ while (FunTmpl->getPreviousDeclaration())
+ FunTmpl = FunTmpl->getPreviousDeclaration();
+ return FunTmpl;
+ }
+
if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
while (Var->getPreviousDeclaration())
Var = Var->getPreviousDeclaration();
@@ -2143,7 +2342,7 @@ QualType ASTContext::getCFConstantStringType() {
SourceLocation(), 0,
FieldTypes[i], /*BitWidth=*/0,
/*Mutable=*/false);
- CFConstantStringTypeDecl->addDecl(*this, Field);
+ CFConstantStringTypeDecl->addDecl(Field);
}
CFConstantStringTypeDecl->completeDefinition(*this);
@@ -2179,7 +2378,7 @@ QualType ASTContext::getObjCFastEnumerationStateType()
SourceLocation(), 0,
FieldTypes[i], /*BitWidth=*/0,
/*Mutable=*/false);
- ObjCFastEnumerationStateTypeDecl->addDecl(*this, Field);
+ ObjCFastEnumerationStateTypeDecl->addDecl(Field);
}
ObjCFastEnumerationStateTypeDecl->completeDefinition(*this);
@@ -2306,7 +2505,7 @@ void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
if (const ObjCCategoryImplDecl *CID =
dyn_cast<ObjCCategoryImplDecl>(Container)) {
for (ObjCCategoryImplDecl::propimpl_iterator
- i = CID->propimpl_begin(*this), e = CID->propimpl_end(*this);
+ i = CID->propimpl_begin(), e = CID->propimpl_end();
i != e; ++i) {
ObjCPropertyImplDecl *PID = *i;
if (PID->getPropertyDecl() == PD) {
@@ -2320,7 +2519,7 @@ void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
} else {
const ObjCImplementationDecl *OID=cast<ObjCImplementationDecl>(Container);
for (ObjCCategoryImplDecl::propimpl_iterator
- i = OID->propimpl_begin(*this), e = OID->propimpl_end(*this);
+ i = OID->propimpl_begin(), e = OID->propimpl_end();
i != e; ++i) {
ObjCPropertyImplDecl *PID = *i;
if (PID->getPropertyDecl() == PD) {
@@ -2611,8 +2810,8 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
}
if (ExpandStructures) {
S += '=';
- for (RecordDecl::field_iterator Field = RDecl->field_begin(*this),
- FieldEnd = RDecl->field_end(*this);
+ for (RecordDecl::field_iterator Field = RDecl->field_begin(),
+ FieldEnd = RDecl->field_end();
Field != FieldEnd; ++Field) {
if (FD) {
S += '"';
@@ -2834,7 +3033,7 @@ QualType ASTContext::getFromTargetType(unsigned Type) const {
bool ASTContext::isObjCNSObjectType(QualType Ty) const {
if (TypedefType *TDT = dyn_cast<TypedefType>(Ty)) {
if (TypedefDecl *TD = TDT->getDecl())
- if (TD->getAttr<ObjCNSObjectAttr>(*const_cast<ASTContext*>(this)))
+ if (TD->getAttr<ObjCNSObjectAttr>())
return true;
}
return false;
@@ -3578,7 +3777,7 @@ static QualType DecodeTypeFromStr(const char *&Str, ASTContext &Context,
case 'P': {
IdentifierInfo *II = &Context.Idents.get("FILE");
DeclContext::lookup_result Lookup
- = Context.getTranslationUnitDecl()->lookup(Context, II);
+ = Context.getTranslationUnitDecl()->lookup(II);
if (Lookup.first != Lookup.second && isa<TypeDecl>(*Lookup.first)) {
Type = Context.getTypeDeclType(cast<TypeDecl>(*Lookup.first));
break;
diff --git a/lib/AST/CFG.cpp b/lib/AST/CFG.cpp
index d7a830726fa4..69852f5fea57 100644
--- a/lib/AST/CFG.cpp
+++ b/lib/AST/CFG.cpp
@@ -556,7 +556,7 @@ CFGBlock* CFGBuilder::VisitNullStmt(NullStmt* Statement) {
CFGBlock* CFGBuilder::VisitCompoundStmt(CompoundStmt* C) {
- CFGBlock* LastBlock = NULL;
+ CFGBlock* LastBlock = Block;
for (CompoundStmt::reverse_body_iterator I=C->body_rbegin(), E=C->body_rend();
I != E; ++I ) {
@@ -1484,10 +1484,11 @@ class VISIBILITY_HIDDEN StmtPrinterHelper : public PrinterHelper {
StmtMapTy StmtMap;
signed CurrentBlock;
unsigned CurrentStmt;
-
+ const LangOptions &LangOpts;
public:
- StmtPrinterHelper(const CFG* cfg) : CurrentBlock(0), CurrentStmt(0) {
+ StmtPrinterHelper(const CFG* cfg, const LangOptions &LO)
+ : CurrentBlock(0), CurrentStmt(0), LangOpts(LO) {
for (CFG::const_iterator I = cfg->begin(), E = cfg->end(); I != E; ++I ) {
unsigned j = 1;
for (CFGBlock::const_iterator BI = I->begin(), BEnd = I->end() ;
@@ -1498,6 +1499,7 @@ public:
virtual ~StmtPrinterHelper() {}
+ const LangOptions &getLangOpts() const { return LangOpts; }
void setBlockID(signed i) { CurrentBlock = i; }
void setStmtID(unsigned i) { CurrentStmt = i; }
@@ -1516,7 +1518,10 @@ public:
return true;
}
};
+} // end anonymous namespace
+
+namespace {
class VISIBILITY_HIDDEN CFGBlockTerminatorPrint
: public StmtVisitor<CFGBlockTerminatorPrint,void> {
@@ -1526,7 +1531,7 @@ class VISIBILITY_HIDDEN CFGBlockTerminatorPrint
public:
CFGBlockTerminatorPrint(llvm::raw_ostream& os, StmtPrinterHelper* helper,
- const PrintingPolicy &Policy = PrintingPolicy())
+ const PrintingPolicy &Policy)
: OS(os), Helper(helper), Policy(Policy) {}
void VisitIfStmt(IfStmt* I) {
@@ -1602,9 +1607,11 @@ public:
E->printPretty(OS, Helper, Policy);
}
};
+} // end anonymous namespace
+
-
-void print_stmt(llvm::raw_ostream&OS, StmtPrinterHelper* Helper, Stmt* Terminator) {
+static void print_stmt(llvm::raw_ostream &OS, StmtPrinterHelper* Helper,
+ Stmt* Terminator) {
if (Helper) {
// special printing for statement-expressions.
if (StmtExpr* SE = dyn_cast<StmtExpr>(Terminator)) {
@@ -1629,14 +1636,15 @@ void print_stmt(llvm::raw_ostream&OS, StmtPrinterHelper* Helper, Stmt* Terminato
}
}
- Terminator->printPretty(OS, Helper, /*FIXME:*/PrintingPolicy());
+ Terminator->printPretty(OS, Helper, PrintingPolicy(Helper->getLangOpts()));
// Expressions need a newline.
if (isa<Expr>(Terminator)) OS << '\n';
}
-void print_block(llvm::raw_ostream& OS, const CFG* cfg, const CFGBlock& B,
- StmtPrinterHelper* Helper, bool print_edges) {
+static void print_block(llvm::raw_ostream& OS, const CFG* cfg,
+ const CFGBlock& B,
+ StmtPrinterHelper* Helper, bool print_edges) {
if (Helper) Helper->setBlockID(B.getBlockID());
@@ -1662,10 +1670,12 @@ void print_block(llvm::raw_ostream& OS, const CFG* cfg, const CFGBlock& B,
OS << L->getName();
else if (CaseStmt* C = dyn_cast<CaseStmt>(Terminator)) {
OS << "case ";
- C->getLHS()->printPretty(OS, Helper, /*FIXME:*/PrintingPolicy());
+ C->getLHS()->printPretty(OS, Helper,
+ PrintingPolicy(Helper->getLangOpts()));
if (C->getRHS()) {
OS << " ... ";
- C->getRHS()->printPretty(OS, Helper, /*FIXME:*/PrintingPolicy());
+ C->getRHS()->printPretty(OS, Helper,
+ PrintingPolicy(Helper->getLangOpts()));
}
}
else if (isa<DefaultStmt>(Terminator))
@@ -1703,7 +1713,8 @@ void print_block(llvm::raw_ostream& OS, const CFG* cfg, const CFGBlock& B,
if (Helper) Helper->setBlockID(-1);
- CFGBlockTerminatorPrint TPrinter(OS, Helper, /*FIXME*/PrintingPolicy());
+ CFGBlockTerminatorPrint TPrinter(OS, Helper,
+ PrintingPolicy(Helper->getLangOpts()));
TPrinter.Visit(const_cast<Stmt*>(B.getTerminator()));
OS << '\n';
}
@@ -1741,15 +1752,13 @@ void print_block(llvm::raw_ostream& OS, const CFG* cfg, const CFGBlock& B,
}
}
-} // end anonymous namespace
/// dump - A simple pretty printer of a CFG that outputs to stderr.
-void CFG::dump() const { print(llvm::errs()); }
+void CFG::dump(const LangOptions &LO) const { print(llvm::errs(), LO); }
/// print - A simple pretty printer of a CFG that outputs to an ostream.
-void CFG::print(llvm::raw_ostream& OS) const {
-
- StmtPrinterHelper Helper(this);
+void CFG::print(llvm::raw_ostream &OS, const LangOptions &LO) const {
+ StmtPrinterHelper Helper(this, LO);
// Print the entry block.
print_block(OS, this, getEntry(), &Helper, true);
@@ -1769,18 +1778,22 @@ void CFG::print(llvm::raw_ostream& OS) const {
}
/// dump - A simply pretty printer of a CFGBlock that outputs to stderr.
-void CFGBlock::dump(const CFG* cfg) const { print(llvm::errs(), cfg); }
+void CFGBlock::dump(const CFG* cfg, const LangOptions &LO) const {
+ print(llvm::errs(), cfg, LO);
+}
/// print - A simple pretty printer of a CFGBlock that outputs to an ostream.
/// Generally this will only be called from CFG::print.
-void CFGBlock::print(llvm::raw_ostream& OS, const CFG* cfg) const {
- StmtPrinterHelper Helper(cfg);
+void CFGBlock::print(llvm::raw_ostream& OS, const CFG* cfg,
+ const LangOptions &LO) const {
+ StmtPrinterHelper Helper(cfg, LO);
print_block(OS, cfg, *this, &Helper, true);
}
/// printTerminator - A simple pretty printer of the terminator of a CFGBlock.
-void CFGBlock::printTerminator(llvm::raw_ostream& OS) const {
- CFGBlockTerminatorPrint TPrinter(OS,NULL);
+void CFGBlock::printTerminator(llvm::raw_ostream &OS,
+ const LangOptions &LO) const {
+ CFGBlockTerminatorPrint TPrinter(OS, NULL, PrintingPolicy(LO));
TPrinter.Visit(const_cast<Stmt*>(getTerminator()));
}
@@ -1872,9 +1885,9 @@ bool CFGBlock::hasBinaryBranchTerminator() const {
static StmtPrinterHelper* GraphHelper;
#endif
-void CFG::viewCFG() const {
+void CFG::viewCFG(const LangOptions &LO) const {
#ifndef NDEBUG
- StmtPrinterHelper H(this);
+ StmtPrinterHelper H(this, LO);
GraphHelper = &H;
llvm::ViewGraph(this,"CFG");
GraphHelper = NULL;
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 5382ab52ab5b..3d02150b65bf 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -41,7 +41,7 @@ void Attr::Destroy(ASTContext &C) {
TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) {
- return new (C) TranslationUnitDecl();
+ return new (C) TranslationUnitDecl(C);
}
NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC,
@@ -226,8 +226,7 @@ std::string NamedDecl::getQualifiedNameAsString() const {
if (const ClassTemplateSpecializationDecl *Spec
= dyn_cast<ClassTemplateSpecializationDecl>(Ctx)) {
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
- PrintingPolicy Policy;
- Policy.CPlusPlus = true;
+ PrintingPolicy Policy(getASTContext().getLangOptions());
std::string TemplateArgsStr
= TemplateSpecializationType::PrintTemplateArgumentList(
TemplateArgs.getFlatArgumentList(),
@@ -372,20 +371,15 @@ void FunctionDecl::Destroy(ASTContext& C) {
C.Deallocate(ParamInfo);
- if (TemplateSpecializationInfo *Info
- = TemplateOrSpecialization.dyn_cast<TemplateSpecializationInfo*>())
- C.Deallocate(Info);
-
Decl::Destroy(C);
}
-Stmt *FunctionDecl::getBody(ASTContext &Context,
- const FunctionDecl *&Definition) const {
+Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const {
for (const FunctionDecl *FD = this; FD != 0; FD = FD->PreviousDeclaration) {
if (FD->Body) {
Definition = FD;
- return FD->Body.get(Context.getExternalSource());
+ return FD->Body.get(getASTContext().getExternalSource());
}
}
@@ -417,14 +411,14 @@ bool FunctionDecl::isExternC(ASTContext &Context) const {
// In C, any non-static, non-overloadable function has external
// linkage.
if (!Context.getLangOptions().CPlusPlus)
- return getStorageClass() != Static && !getAttr<OverloadableAttr>(Context);
+ return getStorageClass() != Static && !getAttr<OverloadableAttr>();
for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit();
DC = DC->getParent()) {
if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC)) {
if (Linkage->getLanguage() == LinkageSpecDecl::lang_c)
return getStorageClass() != Static &&
- !getAttr<OverloadableAttr>(Context);
+ !getAttr<OverloadableAttr>();
break;
}
@@ -489,7 +483,7 @@ unsigned FunctionDecl::getBuiltinID(ASTContext &Context) const {
if (isa<LinkageSpecDecl>(getDeclContext()) &&
cast<LinkageSpecDecl>(getDeclContext())->getLanguage()
== LinkageSpecDecl::lang_c &&
- !getAttr<OverloadableAttr>(Context))
+ !getAttr<OverloadableAttr>())
return BuiltinID;
// Not a builtin
@@ -540,12 +534,12 @@ unsigned FunctionDecl::getMinRequiredArguments() const {
}
bool FunctionDecl::hasActiveGNUInlineAttribute(ASTContext &Context) const {
- if (!isInline() || !hasAttr<GNUInlineAttr>(Context))
+ if (!isInline() || !hasAttr<GNUInlineAttr>())
return false;
for (const FunctionDecl *FD = getPreviousDeclaration(); FD;
FD = FD->getPreviousDeclaration()) {
- if (FD->isInline() && !FD->hasAttr<GNUInlineAttr>(Context))
+ if (FD->isInline() && !FD->hasAttr<GNUInlineAttr>())
return false;
}
@@ -557,12 +551,24 @@ bool FunctionDecl::isExternGNUInline(ASTContext &Context) const {
return false;
for (const FunctionDecl *FD = this; FD; FD = FD->getPreviousDeclaration())
- if (FD->getStorageClass() == Extern && FD->hasAttr<GNUInlineAttr>(Context))
+ if (FD->getStorageClass() == Extern && FD->hasAttr<GNUInlineAttr>())
return true;
return false;
}
+void
+FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) {
+ PreviousDeclaration = PrevDecl;
+
+ if (FunctionTemplateDecl *FunTmpl = getDescribedFunctionTemplate()) {
+ FunctionTemplateDecl *PrevFunTmpl
+ = PrevDecl? PrevDecl->getDescribedFunctionTemplate() : 0;
+ assert((!PrevDecl || PrevFunTmpl) && "Function/function template mismatch");
+ FunTmpl->setPreviousDeclaration(PrevFunTmpl);
+ }
+}
+
/// getOverloadedOperator - Which C++ overloaded operator this
/// function represents, if any.
OverloadedOperatorKind FunctionDecl::getOverloadedOperator() const {
@@ -572,18 +578,64 @@ OverloadedOperatorKind FunctionDecl::getOverloadedOperator() const {
return OO_None;
}
+FunctionTemplateDecl *FunctionDecl::getPrimaryTemplate() const {
+ if (FunctionTemplateSpecializationInfo *Info
+ = TemplateOrSpecialization
+ .dyn_cast<FunctionTemplateSpecializationInfo*>()) {
+ return Info->Template.getPointer();
+ }
+ return 0;
+}
+
+const TemplateArgumentList *
+FunctionDecl::getTemplateSpecializationArgs() const {
+ if (FunctionTemplateSpecializationInfo *Info
+ = TemplateOrSpecialization
+ .dyn_cast<FunctionTemplateSpecializationInfo*>()) {
+ return Info->TemplateArguments;
+ }
+ return 0;
+}
+
void
FunctionDecl::setFunctionTemplateSpecialization(ASTContext &Context,
FunctionTemplateDecl *Template,
- const TemplateArgumentList *TemplateArgs) {
- TemplateSpecializationInfo *Info
- = TemplateOrSpecialization.dyn_cast<TemplateSpecializationInfo*>();
+ const TemplateArgumentList *TemplateArgs,
+ void *InsertPos) {
+ FunctionTemplateSpecializationInfo *Info
+ = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
if (!Info)
- Info = new (Context) TemplateSpecializationInfo;
+ Info = new (Context) FunctionTemplateSpecializationInfo;
- Info->Template = Template;
+ Info->Function = this;
+ Info->Template.setPointer(Template);
+ Info->Template.setInt(0); // Implicit instantiation, unless told otherwise
Info->TemplateArguments = TemplateArgs;
TemplateOrSpecialization = Info;
+
+ // Insert this function template specialization into the set of known
+ // function template specialiations.
+ Template->getSpecializations().InsertNode(Info, InsertPos);
+}
+
+bool FunctionDecl::isExplicitSpecialization() const {
+ // FIXME: check this property for explicit specializations of member
+ // functions of class templates.
+ FunctionTemplateSpecializationInfo *Info
+ = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
+ if (!Info)
+ return false;
+
+ return Info->isExplicitSpecialization();
+}
+
+void FunctionDecl::setExplicitSpecialization(bool ES) {
+ // FIXME: set this property for explicit specializations of member functions
+ // of class templates.
+ FunctionTemplateSpecializationInfo *Info
+ = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
+ if (Info)
+ Info->setExplicitSpecialization(ES);
}
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 5815d820aef6..96ba19b9a6b9 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -157,6 +157,25 @@ void Decl::setLexicalDeclContext(DeclContext *DC) {
}
}
+TranslationUnitDecl *Decl::getTranslationUnitDecl() {
+ if (TranslationUnitDecl *TUD = dyn_cast<TranslationUnitDecl>(this))
+ return TUD;
+
+ DeclContext *DC = getDeclContext();
+ assert(DC && "This decl is not contained in a translation unit!");
+
+ while (!DC->isTranslationUnit()) {
+ DC = DC->getParent();
+ assert(DC && "This decl is not contained in a translation unit!");
+ }
+
+ return cast<TranslationUnitDecl>(DC);
+}
+
+ASTContext &Decl::getASTContext() const {
+ return getTranslationUnitDecl()->getASTContext();
+}
+
unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
switch (DeclKind) {
default:
@@ -226,8 +245,8 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
}
}
-void Decl::addAttr(ASTContext &Context, Attr *NewAttr) {
- Attr *&ExistingAttr = Context.getDeclAttrs(this);
+void Decl::addAttr(Attr *NewAttr) {
+ Attr *&ExistingAttr = getASTContext().getDeclAttrs(this);
NewAttr->setNext(ExistingAttr);
ExistingAttr = NewAttr;
@@ -235,19 +254,19 @@ void Decl::addAttr(ASTContext &Context, Attr *NewAttr) {
HasAttrs = true;
}
-void Decl::invalidateAttrs(ASTContext &Context) {
+void Decl::invalidateAttrs() {
if (!HasAttrs) return;
HasAttrs = false;
- Context.eraseDeclAttrs(this);
+ getASTContext().eraseDeclAttrs(this);
}
-const Attr *Decl::getAttrsImpl(ASTContext &Context) const {
+const Attr *Decl::getAttrsImpl() const {
assert(HasAttrs && "getAttrs() should verify this!");
- return Context.getDeclAttrs(this);
+ return getASTContext().getDeclAttrs(this);
}
-void Decl::swapAttrs(ASTContext &Context, Decl *RHS) {
+void Decl::swapAttrs(Decl *RHS) {
bool HasLHSAttr = this->HasAttrs;
bool HasRHSAttr = RHS->HasAttrs;
@@ -256,7 +275,9 @@ void Decl::swapAttrs(ASTContext &Context, Decl *RHS) {
// If 'this' has no attrs, swap the other way.
if (!HasLHSAttr)
- return RHS->swapAttrs(Context, this);
+ return RHS->swapAttrs(this);
+
+ ASTContext &Context = getASTContext();
// Handle the case when both decls have attrs.
if (HasRHSAttr) {
@@ -276,7 +297,7 @@ void Decl::Destroy(ASTContext &C) {
// Free attributes for this decl.
if (HasAttrs) {
C.getDeclAttrs(this)->Destroy(C);
- invalidateAttrs(C);
+ invalidateAttrs();
HasAttrs = false;
}
@@ -339,12 +360,12 @@ DeclContext *Decl::castToDeclContext(const Decl *D) {
}
}
-CompoundStmt* Decl::getCompoundBody(ASTContext &Context) const {
- return dyn_cast_or_null<CompoundStmt>(getBody(Context));
+CompoundStmt* Decl::getCompoundBody() const {
+ return dyn_cast_or_null<CompoundStmt>(getBody());
}
-SourceLocation Decl::getBodyRBrace(ASTContext &Context) const {
- Stmt *Body = getBody(Context);
+SourceLocation Decl::getBodyRBrace() const {
+ Stmt *Body = getBody();
if (!Body)
return SourceLocation();
if (CompoundStmt *CS = dyn_cast<CompoundStmt>(Body))
@@ -388,7 +409,7 @@ DeclContext::~DeclContext() {
}
void DeclContext::DestroyDecls(ASTContext &C) {
- for (decl_iterator D = decls_begin(C); D != decls_end(C); )
+ for (decl_iterator D = decls_begin(); D != decls_end(); )
(*D++)->Destroy(C);
}
@@ -479,8 +500,8 @@ DeclContext *DeclContext::getNextContext() {
/// \brief Load the declarations within this lexical storage from an
/// external source.
void
-DeclContext::LoadLexicalDeclsFromExternalStorage(ASTContext &Context) const {
- ExternalASTSource *Source = Context.getExternalSource();
+DeclContext::LoadLexicalDeclsFromExternalStorage() const {
+ ExternalASTSource *Source = getParentASTContext().getExternalSource();
assert(hasExternalLexicalStorage() && Source && "No external storage?");
llvm::SmallVector<uint32_t, 64> Decls;
@@ -517,9 +538,9 @@ DeclContext::LoadLexicalDeclsFromExternalStorage(ASTContext &Context) const {
}
void
-DeclContext::LoadVisibleDeclsFromExternalStorage(ASTContext &Context) const {
+DeclContext::LoadVisibleDeclsFromExternalStorage() const {
DeclContext *This = const_cast<DeclContext *>(this);
- ExternalASTSource *Source = Context.getExternalSource();
+ ExternalASTSource *Source = getParentASTContext().getExternalSource();
assert(hasExternalVisibleStorage() && Source && "No external storage?");
llvm::SmallVector<VisibleDeclaration, 64> Decls;
@@ -539,30 +560,30 @@ DeclContext::LoadVisibleDeclsFromExternalStorage(ASTContext &Context) const {
}
}
-DeclContext::decl_iterator DeclContext::decls_begin(ASTContext &Context) const {
+DeclContext::decl_iterator DeclContext::decls_begin() const {
if (hasExternalLexicalStorage())
- LoadLexicalDeclsFromExternalStorage(Context);
+ LoadLexicalDeclsFromExternalStorage();
// FIXME: Check whether we need to load some declarations from
// external storage.
return decl_iterator(FirstDecl);
}
-DeclContext::decl_iterator DeclContext::decls_end(ASTContext &Context) const {
+DeclContext::decl_iterator DeclContext::decls_end() const {
if (hasExternalLexicalStorage())
- LoadLexicalDeclsFromExternalStorage(Context);
+ LoadLexicalDeclsFromExternalStorage();
return decl_iterator();
}
-bool DeclContext::decls_empty(ASTContext &Context) const {
+bool DeclContext::decls_empty() const {
if (hasExternalLexicalStorage())
- LoadLexicalDeclsFromExternalStorage(Context);
+ LoadLexicalDeclsFromExternalStorage();
return !FirstDecl;
}
-void DeclContext::addDecl(ASTContext &Context, Decl *D) {
+void DeclContext::addDecl(Decl *D) {
assert(D->getLexicalDeclContext() == this &&
"Decl inserted into wrong lexical context");
assert(!D->getNextDeclInContext() && D != LastDecl &&
@@ -576,44 +597,44 @@ void DeclContext::addDecl(ASTContext &Context, Decl *D) {
}
if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
- ND->getDeclContext()->makeDeclVisibleInContext(Context, ND);
+ ND->getDeclContext()->makeDeclVisibleInContext(ND);
}
/// buildLookup - Build the lookup data structure with all of the
/// declarations in DCtx (and any other contexts linked to it or
/// transparent contexts nested within it).
-void DeclContext::buildLookup(ASTContext &Context, DeclContext *DCtx) {
+void DeclContext::buildLookup(DeclContext *DCtx) {
for (; DCtx; DCtx = DCtx->getNextContext()) {
- for (decl_iterator D = DCtx->decls_begin(Context),
- DEnd = DCtx->decls_end(Context);
+ for (decl_iterator D = DCtx->decls_begin(),
+ DEnd = DCtx->decls_end();
D != DEnd; ++D) {
// Insert this declaration into the lookup structure
if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
- makeDeclVisibleInContextImpl(Context, ND);
+ makeDeclVisibleInContextImpl(ND);
// If this declaration is itself a transparent declaration context,
// add its members (recursively).
if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D))
if (InnerCtx->isTransparentContext())
- buildLookup(Context, InnerCtx->getPrimaryContext());
+ buildLookup(InnerCtx->getPrimaryContext());
}
}
}
DeclContext::lookup_result
-DeclContext::lookup(ASTContext &Context, DeclarationName Name) {
+DeclContext::lookup(DeclarationName Name) {
DeclContext *PrimaryContext = getPrimaryContext();
if (PrimaryContext != this)
- return PrimaryContext->lookup(Context, Name);
+ return PrimaryContext->lookup(Name);
if (hasExternalVisibleStorage())
- LoadVisibleDeclsFromExternalStorage(Context);
+ LoadVisibleDeclsFromExternalStorage();
/// If there is no lookup data structure, build one now by walking
/// all of the linked DeclContexts (in declaration order!) and
/// inserting their values.
if (!LookupPtr) {
- buildLookup(Context, this);
+ buildLookup(this);
if (!LookupPtr)
return lookup_result(0, 0);
@@ -623,12 +644,12 @@ DeclContext::lookup(ASTContext &Context, DeclarationName Name) {
StoredDeclsMap::iterator Pos = Map->find(Name);
if (Pos == Map->end())
return lookup_result(0, 0);
- return Pos->second.getLookupResult(Context);
+ return Pos->second.getLookupResult(getParentASTContext());
}
DeclContext::lookup_const_result
-DeclContext::lookup(ASTContext &Context, DeclarationName Name) const {
- return const_cast<DeclContext*>(this)->lookup(Context, Name);
+DeclContext::lookup(DeclarationName Name) const {
+ return const_cast<DeclContext*>(this)->lookup(Name);
}
DeclContext *DeclContext::getLookupContext() {
@@ -647,7 +668,7 @@ DeclContext *DeclContext::getEnclosingNamespaceContext() {
return Ctx->getPrimaryContext();
}
-void DeclContext::makeDeclVisibleInContext(ASTContext &Context, NamedDecl *D) {
+void DeclContext::makeDeclVisibleInContext(NamedDecl *D) {
// FIXME: This feels like a hack. Should DeclarationName support
// template-ids, or is there a better way to keep specializations
// from being visible?
@@ -656,7 +677,7 @@ void DeclContext::makeDeclVisibleInContext(ASTContext &Context, NamedDecl *D) {
DeclContext *PrimaryContext = getPrimaryContext();
if (PrimaryContext != this) {
- PrimaryContext->makeDeclVisibleInContext(Context, D);
+ PrimaryContext->makeDeclVisibleInContext(D);
return;
}
@@ -664,16 +685,15 @@ void DeclContext::makeDeclVisibleInContext(ASTContext &Context, NamedDecl *D) {
// into it. Otherwise, be lazy and don't build that structure until
// someone asks for it.
if (LookupPtr)
- makeDeclVisibleInContextImpl(Context, D);
+ makeDeclVisibleInContextImpl(D);
// If we are a transparent context, insert into our parent context,
// too. This operation is recursive.
if (isTransparentContext())
- getParent()->makeDeclVisibleInContext(Context, D);
+ getParent()->makeDeclVisibleInContext(D);
}
-void DeclContext::makeDeclVisibleInContextImpl(ASTContext &Context,
- NamedDecl *D) {
+void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D) {
// Skip unnamed declarations.
if (!D->getDeclName())
return;
@@ -698,7 +718,7 @@ void DeclContext::makeDeclVisibleInContextImpl(ASTContext &Context,
// If it is possible that this is a redeclaration, check to see if there is
// already a decl for which declarationReplaces returns true. If there is
// one, just replace it and return.
- if (DeclNameEntries.HandleRedeclaration(Context, D))
+ if (DeclNameEntries.HandleRedeclaration(getParentASTContext(), D))
return;
// Put this declaration into the appropriate slot.
@@ -708,8 +728,8 @@ void DeclContext::makeDeclVisibleInContextImpl(ASTContext &Context,
/// Returns iterator range [First, Last) of UsingDirectiveDecls stored within
/// this context.
DeclContext::udir_iterator_range
-DeclContext::getUsingDirectives(ASTContext &Context) const {
- lookup_const_result Result = lookup(Context, UsingDirectiveDecl::getName());
+DeclContext::getUsingDirectives() const {
+ lookup_const_result Result = lookup(UsingDirectiveDecl::getName());
return udir_iterator_range(reinterpret_cast<udir_iterator>(Result.first),
reinterpret_cast<udir_iterator>(Result.second));
}
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 752218db042a..b8b29528066d 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -44,11 +44,16 @@ CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
}
CXXRecordDecl::~CXXRecordDecl() {
- delete [] Bases;
+}
+
+void CXXRecordDecl::Destroy(ASTContext &C) {
+ C.Deallocate(Bases);
+ this->RecordDecl::Destroy(C);
}
void
-CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
+CXXRecordDecl::setBases(ASTContext &C,
+ CXXBaseSpecifier const * const *Bases,
unsigned NumBases) {
// C++ [dcl.init.aggr]p1:
// An aggregate is an array or a class (clause 9) with [...]
@@ -56,10 +61,9 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
Aggregate = false;
if (this->Bases)
- delete [] this->Bases;
+ C.Deallocate(this->Bases);
- // FIXME: allocate using the ASTContext
- this->Bases = new CXXBaseSpecifier[NumBases];
+ this->Bases = new(C) CXXBaseSpecifier [NumBases];
this->NumBases = NumBases;
for (unsigned i = 0; i < NumBases; ++i)
this->Bases[i] = *Bases[i];
@@ -78,7 +82,7 @@ CXXConstructorDecl *CXXRecordDecl::getCopyConstructor(ASTContext &Context,
Context.getCanonicalType(ClassType));
unsigned FoundTQs;
DeclContext::lookup_const_iterator Con, ConEnd;
- for (llvm::tie(Con, ConEnd) = this->lookup(Context, ConstructorName);
+ for (llvm::tie(Con, ConEnd) = this->lookup(ConstructorName);
Con != ConEnd; ++Con) {
if (cast<CXXConstructorDecl>(*Con)->isCopyConstructor(Context,
FoundTQs)) {
@@ -97,7 +101,7 @@ bool CXXRecordDecl::hasConstCopyAssignment(ASTContext &Context) const {
DeclarationName OpName =Context.DeclarationNames.getCXXOperatorName(OO_Equal);
DeclContext::lookup_const_iterator Op, OpEnd;
- for (llvm::tie(Op, OpEnd) = this->lookup(Context, OpName);
+ for (llvm::tie(Op, OpEnd) = this->lookup(OpName);
Op != OpEnd; ++Op) {
// C++ [class.copy]p9:
// A user-declared copy assignment operator is a non-static non-template
@@ -201,7 +205,7 @@ CXXRecordDecl::getDefaultConstructor(ASTContext &Context) {
Context.getCanonicalType(ClassType.getUnqualifiedType()));
DeclContext::lookup_const_iterator Con, ConEnd;
- for (llvm::tie(Con, ConEnd) = lookup(Context, ConstructorName);
+ for (llvm::tie(Con, ConEnd) = lookup(ConstructorName);
Con != ConEnd; ++Con) {
CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
if (Constructor->isDefaultConstructor())
@@ -218,7 +222,7 @@ CXXRecordDecl::getDestructor(ASTContext &Context) {
= Context.DeclarationNames.getCXXDestructorName(ClassType);
DeclContext::lookup_iterator I, E;
- llvm::tie(I, E) = lookup(Context, Name);
+ llvm::tie(I, E) = lookup(Name);
assert(I != E && "Did not find a destructor!");
const CXXDestructorDecl *Dtor = cast<CXXDestructorDecl>(*I);
@@ -294,8 +298,9 @@ QualType CXXMethodDecl::getThisType(ASTContext &C) const {
}
CXXBaseOrMemberInitializer::
-CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs)
- : Args(0), NumArgs(0) {
+CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs,
+ SourceLocation L)
+ : Args(0), NumArgs(0), IdLoc(L) {
BaseOrMember = reinterpret_cast<uintptr_t>(BaseType.getTypePtr());
assert((BaseOrMember & 0x01) == 0 && "Invalid base class type pointer");
BaseOrMember |= 0x01;
@@ -309,8 +314,9 @@ CXXBaseOrMemberInitializer(QualType BaseType, Expr **Args, unsigned NumArgs)
}
CXXBaseOrMemberInitializer::
-CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs)
- : Args(0), NumArgs(0) {
+CXXBaseOrMemberInitializer(FieldDecl *Member, Expr **Args, unsigned NumArgs,
+ SourceLocation L)
+ : Args(0), NumArgs(0), IdLoc(L) {
BaseOrMember = reinterpret_cast<uintptr_t>(Member);
assert((BaseOrMember & 0x01) == 0 && "Invalid member pointer");
@@ -405,6 +411,27 @@ CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
isImplicitlyDeclared);
}
+void
+CXXConstructorDecl::setBaseOrMemberInitializers(
+ ASTContext &C,
+ CXXBaseOrMemberInitializer **Initializers,
+ unsigned NumInitializers) {
+ if (NumInitializers > 0) {
+ NumBaseOrMemberInitializers = NumInitializers;
+ BaseOrMemberInitializers =
+ new (C, 8) CXXBaseOrMemberInitializer*[NumInitializers];
+ for (unsigned Idx = 0; Idx < NumInitializers; ++Idx)
+ BaseOrMemberInitializers[Idx] = Initializers[Idx];
+ }
+}
+
+void
+CXXConstructorDecl::Destroy(ASTContext& C) {
+ C.Deallocate(BaseOrMemberInitializers);
+ this->~CXXMethodDecl();
+ C.Deallocate((void *)this);
+}
+
CXXConversionDecl *
CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
@@ -420,13 +447,9 @@ OverloadedFunctionDecl::Create(ASTContext &C, DeclContext *DC,
return new (C) OverloadedFunctionDecl(DC, N);
}
-void OverloadedFunctionDecl::addOverload(FunctionTemplateDecl *FTD) {
- Functions.push_back(FTD);
-
- // An overloaded function declaration always has the location of
- // the most-recently-added function declaration.
- if (FTD->getLocation().isValid())
- this->setLocation(FTD->getLocation());
+void OverloadedFunctionDecl::addOverload(AnyFunctionDecl F) {
+ Functions.push_back(F);
+ this->setLocation(F.get()->getLocation());
}
LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 60a96d0471ab..54f13e14ba65 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -45,10 +45,9 @@ void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {
/// getIvarDecl - This method looks up an ivar in this ContextDecl.
///
ObjCIvarDecl *
-ObjCContainerDecl::getIvarDecl(ASTContext &Context, IdentifierInfo *Id) const {
+ObjCContainerDecl::getIvarDecl(IdentifierInfo *Id) const {
lookup_const_iterator Ivar, IvarEnd;
- for (llvm::tie(Ivar, IvarEnd) = lookup(Context, Id);
- Ivar != IvarEnd; ++Ivar) {
+ for (llvm::tie(Ivar, IvarEnd) = lookup(Id); Ivar != IvarEnd; ++Ivar) {
if (ObjCIvarDecl *ivar = dyn_cast<ObjCIvarDecl>(*Ivar))
return ivar;
}
@@ -57,7 +56,7 @@ ObjCContainerDecl::getIvarDecl(ASTContext &Context, IdentifierInfo *Id) const {
// Get the local instance method declared in this interface.
ObjCMethodDecl *
-ObjCContainerDecl::getInstanceMethod(ASTContext &Context, Selector Sel) const {
+ObjCContainerDecl::getInstanceMethod(Selector Sel) const {
// Since instance & class methods can have the same name, the loop below
// ensures we get the correct method.
//
@@ -67,8 +66,7 @@ ObjCContainerDecl::getInstanceMethod(ASTContext &Context, Selector Sel) const {
// @end
//
lookup_const_iterator Meth, MethEnd;
- for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
- Meth != MethEnd; ++Meth) {
+ for (llvm::tie(Meth, MethEnd) = lookup(Sel); Meth != MethEnd; ++Meth) {
ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
if (MD && MD->isInstanceMethod())
return MD;
@@ -78,7 +76,7 @@ ObjCContainerDecl::getInstanceMethod(ASTContext &Context, Selector Sel) const {
// Get the local class method declared in this interface.
ObjCMethodDecl *
-ObjCContainerDecl::getClassMethod(ASTContext &Context, Selector Sel) const {
+ObjCContainerDecl::getClassMethod(Selector Sel) const {
// Since instance & class methods can have the same name, the loop below
// ensures we get the correct method.
//
@@ -88,8 +86,7 @@ ObjCContainerDecl::getClassMethod(ASTContext &Context, Selector Sel) const {
// @end
//
lookup_const_iterator Meth, MethEnd;
- for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
- Meth != MethEnd; ++Meth) {
+ for (llvm::tie(Meth, MethEnd) = lookup(Sel); Meth != MethEnd; ++Meth) {
ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
if (MD && MD->isClassMethod())
return MD;
@@ -102,10 +99,8 @@ ObjCContainerDecl::getClassMethod(ASTContext &Context, Selector Sel) const {
/// FIXME: Convert to DeclContext lookup...
///
ObjCPropertyDecl *
-ObjCContainerDecl::FindPropertyDeclaration(ASTContext &Context,
- IdentifierInfo *PropertyId) const {
- for (prop_iterator I = prop_begin(Context), E = prop_end(Context);
- I != E; ++I)
+ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
+ for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I)
if ((*I)->getIdentifier() == PropertyId)
return *I;
@@ -113,8 +108,7 @@ ObjCContainerDecl::FindPropertyDeclaration(ASTContext &Context,
if (PID) {
for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
E = PID->protocol_end(); I != E; ++I)
- if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(Context,
- PropertyId))
+ if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
return P;
}
@@ -122,37 +116,33 @@ ObjCContainerDecl::FindPropertyDeclaration(ASTContext &Context,
// Look through categories.
for (ObjCCategoryDecl *Category = OID->getCategoryList();
Category; Category = Category->getNextClassCategory()) {
- if (ObjCPropertyDecl *P = Category->FindPropertyDeclaration(Context,
- PropertyId))
+ if (ObjCPropertyDecl *P = Category->FindPropertyDeclaration(PropertyId))
return P;
}
// Look through protocols.
for (ObjCInterfaceDecl::protocol_iterator I = OID->protocol_begin(),
E = OID->protocol_end(); I != E; ++I) {
- if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(Context,
- PropertyId))
+ if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
return P;
}
if (OID->getSuperClass())
- return OID->getSuperClass()->FindPropertyDeclaration(Context,
- PropertyId);
+ return OID->getSuperClass()->FindPropertyDeclaration(PropertyId);
} else if (const ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(this)) {
// Look through protocols.
for (ObjCInterfaceDecl::protocol_iterator I = OCD->protocol_begin(),
E = OCD->protocol_end(); I != E; ++I) {
- if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(Context,
- PropertyId))
+ if (ObjCPropertyDecl *P = (*I)->FindPropertyDeclaration(PropertyId))
return P;
}
}
return 0;
}
-ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(
- ASTContext &Context, IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) {
+ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
+ ObjCInterfaceDecl *&clsDeclared) {
ObjCInterfaceDecl* ClassDecl = this;
while (ClassDecl != NULL) {
- if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(Context, ID)) {
+ if (ObjCIvarDecl *I = ClassDecl->getIvarDecl(ID)) {
clsDeclared = ClassDecl;
return I;
}
@@ -177,13 +167,12 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::lookupInheritedClass(
/// lookupInstanceMethod - This method returns an instance method by looking in
/// the class, its categories, and its super classes (using a linear search).
-ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(ASTContext &Context,
- Selector Sel) {
+ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(Selector Sel) {
ObjCInterfaceDecl* ClassDecl = this;
ObjCMethodDecl *MethodDecl = 0;
while (ClassDecl != NULL) {
- if ((MethodDecl = ClassDecl->getInstanceMethod(Context, Sel)))
+ if ((MethodDecl = ClassDecl->getInstanceMethod(Sel)))
return MethodDecl;
// Didn't find one yet - look through protocols.
@@ -191,13 +180,13 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(ASTContext &Context,
ClassDecl->getReferencedProtocols();
for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
E = Protocols.end(); I != E; ++I)
- if ((MethodDecl = (*I)->lookupInstanceMethod(Context, Sel)))
+ if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
return MethodDecl;
// Didn't find one yet - now look through categories.
ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
while (CatDecl) {
- if ((MethodDecl = CatDecl->getInstanceMethod(Context, Sel)))
+ if ((MethodDecl = CatDecl->getInstanceMethod(Sel)))
return MethodDecl;
// Didn't find one yet - look through protocols.
@@ -205,7 +194,7 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(ASTContext &Context,
CatDecl->getReferencedProtocols();
for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
E = Protocols.end(); I != E; ++I)
- if ((MethodDecl = (*I)->lookupInstanceMethod(Context, Sel)))
+ if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
return MethodDecl;
CatDecl = CatDecl->getNextClassCategory();
}
@@ -216,25 +205,24 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupInstanceMethod(ASTContext &Context,
// lookupClassMethod - This method returns a class method by looking in the
// class, its categories, and its super classes (using a linear search).
-ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(ASTContext &Context,
- Selector Sel) {
+ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(Selector Sel) {
ObjCInterfaceDecl* ClassDecl = this;
ObjCMethodDecl *MethodDecl = 0;
while (ClassDecl != NULL) {
- if ((MethodDecl = ClassDecl->getClassMethod(Context, Sel)))
+ if ((MethodDecl = ClassDecl->getClassMethod(Sel)))
return MethodDecl;
// Didn't find one yet - look through protocols.
for (ObjCInterfaceDecl::protocol_iterator I = ClassDecl->protocol_begin(),
E = ClassDecl->protocol_end(); I != E; ++I)
- if ((MethodDecl = (*I)->lookupClassMethod(Context, Sel)))
+ if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
return MethodDecl;
// Didn't find one yet - now look through categories.
ObjCCategoryDecl *CatDecl = ClassDecl->getCategoryList();
while (CatDecl) {
- if ((MethodDecl = CatDecl->getClassMethod(Context, Sel)))
+ if ((MethodDecl = CatDecl->getClassMethod(Sel)))
return MethodDecl;
// Didn't find one yet - look through protocols.
@@ -242,7 +230,7 @@ ObjCMethodDecl *ObjCInterfaceDecl::lookupClassMethod(ASTContext &Context,
CatDecl->getReferencedProtocols();
for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
E = Protocols.end(); I != E; ++I)
- if ((MethodDecl = (*I)->lookupClassMethod(Context, Sel)))
+ if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
return MethodDecl;
CatDecl = CatDecl->getNextClassCategory();
}
@@ -446,30 +434,28 @@ ObjCProtocolDecl *ObjCProtocolDecl::lookupProtocolNamed(IdentifierInfo *Name) {
// lookupInstanceMethod - Lookup a instance method in the protocol and protocols
// it inherited.
-ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(ASTContext &Context,
- Selector Sel) {
+ObjCMethodDecl *ObjCProtocolDecl::lookupInstanceMethod(Selector Sel) {
ObjCMethodDecl *MethodDecl = NULL;
- if ((MethodDecl = getInstanceMethod(Context, Sel)))
+ if ((MethodDecl = getInstanceMethod(Sel)))
return MethodDecl;
for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
- if ((MethodDecl = (*I)->lookupInstanceMethod(Context, Sel)))
+ if ((MethodDecl = (*I)->lookupInstanceMethod(Sel)))
return MethodDecl;
return NULL;
}
// lookupInstanceMethod - Lookup a class method in the protocol and protocols
// it inherited.
-ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(ASTContext &Context,
- Selector Sel) {
+ObjCMethodDecl *ObjCProtocolDecl::lookupClassMethod(Selector Sel) {
ObjCMethodDecl *MethodDecl = NULL;
- if ((MethodDecl = getClassMethod(Context, Sel)))
+ if ((MethodDecl = getClassMethod(Sel)))
return MethodDecl;
for (protocol_iterator I = protocol_begin(), E = protocol_end(); I != E; ++I)
- if ((MethodDecl = (*I)->lookupClassMethod(Context, Sel)))
+ if ((MethodDecl = (*I)->lookupClassMethod(Sel)))
return MethodDecl;
return NULL;
}
@@ -555,11 +541,10 @@ ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
}
-void ObjCImplDecl::addPropertyImplementation(ASTContext &Context,
- ObjCPropertyImplDecl *property) {
+void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) {
// FIXME: The context should be correct before we get here.
property->setLexicalDeclContext(this);
- addDecl(Context, property);
+ addDecl(property);
}
/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
@@ -567,9 +552,8 @@ void ObjCImplDecl::addPropertyImplementation(ASTContext &Context,
/// the implemented property that uses it.
///
ObjCPropertyImplDecl *ObjCImplDecl::
-FindPropertyImplIvarDecl(ASTContext &Context, IdentifierInfo *ivarId) const {
- for (propimpl_iterator i = propimpl_begin(Context), e = propimpl_end(Context);
- i != e; ++i){
+FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
+ for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
ObjCPropertyImplDecl *PID = *i;
if (PID->getPropertyIvarDecl() &&
PID->getPropertyIvarDecl()->getIdentifier() == ivarId)
@@ -583,9 +567,8 @@ FindPropertyImplIvarDecl(ASTContext &Context, IdentifierInfo *ivarId) const {
/// category @implementation block.
///
ObjCPropertyImplDecl *ObjCImplDecl::
-FindPropertyImplDecl(ASTContext &Context, IdentifierInfo *Id) const {
- for (propimpl_iterator i = propimpl_begin(Context), e = propimpl_end(Context);
- i != e; ++i){
+FindPropertyImplDecl(IdentifierInfo *Id) const {
+ for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i){
ObjCPropertyImplDecl *PID = *i;
if (PID->getPropertyDecl()->getIdentifier() == Id)
return PID;
@@ -596,8 +579,7 @@ FindPropertyImplDecl(ASTContext &Context, IdentifierInfo *Id) const {
// getInstanceMethod - This method returns an instance method by looking in
// the class implementation. Unlike interfaces, we don't look outside the
// implementation.
-ObjCMethodDecl *ObjCImplDecl::getInstanceMethod(ASTContext &Context,
- Selector Sel) const {
+ObjCMethodDecl *ObjCImplDecl::getInstanceMethod(Selector Sel) const {
// Since instance & class methods can have the same name, the loop below
// ensures we get the correct method.
//
@@ -607,7 +589,7 @@ ObjCMethodDecl *ObjCImplDecl::getInstanceMethod(ASTContext &Context,
// @end
//
lookup_const_iterator Meth, MethEnd;
- for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
+ for (llvm::tie(Meth, MethEnd) = lookup(Sel);
Meth != MethEnd; ++Meth) {
ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
if (MD && MD->isInstanceMethod())
@@ -619,8 +601,7 @@ ObjCMethodDecl *ObjCImplDecl::getInstanceMethod(ASTContext &Context,
// getClassMethod - This method returns an instance method by looking in
// the class implementation. Unlike interfaces, we don't look outside the
// implementation.
-ObjCMethodDecl *ObjCImplDecl::getClassMethod(ASTContext &Context,
- Selector Sel) const {
+ObjCMethodDecl *ObjCImplDecl::getClassMethod(Selector Sel) const {
// Since instance & class methods can have the same name, the loop below
// ensures we get the correct method.
//
@@ -630,7 +611,7 @@ ObjCMethodDecl *ObjCImplDecl::getClassMethod(ASTContext &Context,
// @end
//
lookup_const_iterator Meth, MethEnd;
- for (llvm::tie(Meth, MethEnd) = lookup(Context, Sel);
+ for (llvm::tie(Meth, MethEnd) = lookup(Sel);
Meth != MethEnd; ++Meth) {
ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(*Meth);
if (MD && MD->isClassMethod())
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 2b06e93295bc..12e89cd80d19 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -74,14 +74,13 @@ namespace {
};
}
-void Decl::print(llvm::raw_ostream &Out, ASTContext &Context,
- unsigned Indentation) {
- print(Out, Context, Context.PrintingPolicy, Indentation);
+void Decl::print(llvm::raw_ostream &Out, unsigned Indentation) {
+ print(Out, getASTContext().PrintingPolicy, Indentation);
}
-void Decl::print(llvm::raw_ostream &Out, ASTContext &Context,
- const PrintingPolicy &Policy, unsigned Indentation) {
- DeclPrinter Printer(Out, Context, Policy, Indentation);
+void Decl::print(llvm::raw_ostream &Out, const PrintingPolicy &Policy,
+ unsigned Indentation) {
+ DeclPrinter Printer(Out, getASTContext(), Policy, Indentation);
Printer.Visit(this);
}
@@ -97,6 +96,8 @@ static QualType GetBaseType(QualType T) {
BaseType = ATy->getElementType();
else if (const FunctionType* FTy = BaseType->getAsFunctionType())
BaseType = FTy->getResultType();
+ else if (const VectorType *VTy = BaseType->getAsVectorType())
+ BaseType = VTy->getElementType();
else
assert(0 && "Unknown declarator!");
}
@@ -112,11 +113,10 @@ static QualType getDeclType(Decl* D) {
}
void Decl::printGroup(Decl** Begin, unsigned NumDecls,
- llvm::raw_ostream &Out, ASTContext &Context,
- const PrintingPolicy &Policy,
+ llvm::raw_ostream &Out, const PrintingPolicy &Policy,
unsigned Indentation) {
if (NumDecls == 1) {
- (*Begin)->print(Out, Context, Policy, Indentation);
+ (*Begin)->print(Out, Policy, Indentation);
return;
}
@@ -127,7 +127,7 @@ void Decl::printGroup(Decl** Begin, unsigned NumDecls,
PrintingPolicy SubPolicy(Policy);
if (TD && TD->isDefinition()) {
- TD->print(Out, Context, Policy, Indentation);
+ TD->print(Out, Policy, Indentation);
Out << " ";
SubPolicy.SuppressTag = true;
}
@@ -142,12 +142,12 @@ void Decl::printGroup(Decl** Begin, unsigned NumDecls,
SubPolicy.SuppressSpecifiers = true;
}
- (*Begin)->print(Out, Context, SubPolicy, Indentation);
+ (*Begin)->print(Out, SubPolicy, Indentation);
}
}
-void Decl::dump(ASTContext &Context) {
- print(llvm::errs(), Context);
+void Decl::dump() {
+ print(llvm::errs());
}
llvm::raw_ostream& DeclPrinter::Indent() {
@@ -158,8 +158,7 @@ llvm::raw_ostream& DeclPrinter::Indent() {
void DeclPrinter::ProcessDeclGroup(llvm::SmallVectorImpl<Decl*>& Decls) {
this->Indent();
- Decl::printGroup(Decls.data(), Decls.size(), Out, Context,
- Policy, Indentation);
+ Decl::printGroup(Decls.data(), Decls.size(), Out, Policy, Indentation);
Out << ";\n";
Decls.clear();
@@ -174,8 +173,7 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) {
Indentation += Policy.Indentation;
llvm::SmallVector<Decl*, 2> Decls;
- for (DeclContext::decl_iterator D = DC->decls_begin(Context),
- DEnd = DC->decls_end(Context);
+ for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end();
D != DEnd; ++D) {
if (!Policy.Dump) {
// Skip over implicit declarations in pretty-printing mode.
@@ -364,7 +362,7 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
} else
Out << ' ';
- D->getBody(Context)->printPretty(Out, Context, 0, SubPolicy, Indentation);
+ D->getBody()->printPretty(Out, Context, 0, SubPolicy, Indentation);
Out << '\n';
}
}
@@ -504,7 +502,7 @@ void DeclPrinter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
VisitDeclContext(D);
Indent() << "}";
} else
- Visit(*D->decls_begin(Context));
+ Visit(*D->decls_begin());
}
void DeclPrinter::VisitTemplateDecl(TemplateDecl *D) {
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 165672d50f4e..f1bd1b67d21e 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -81,11 +81,36 @@ FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
DeclContext *DC,
SourceLocation L,
DeclarationName Name,
- TemplateParameterList *Params,
+ TemplateParameterList *Params,
NamedDecl *Decl) {
return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
}
+void FunctionTemplateDecl::Destroy(ASTContext &C) {
+ if (Common *CommonPtr = CommonOrPrev.dyn_cast<Common*>()) {
+ for (llvm::FoldingSet<FunctionTemplateSpecializationInfo>::iterator
+ Spec = CommonPtr->Specializations.begin(),
+ SpecEnd = CommonPtr->Specializations.end();
+ Spec != SpecEnd; ++Spec)
+ C.Deallocate(&*Spec);
+ }
+
+ Decl::Destroy(C);
+}
+
+FunctionTemplateDecl::Common *FunctionTemplateDecl::getCommonPtr() {
+ // Find the first declaration of this function template.
+ FunctionTemplateDecl *First = this;
+ while (First->getPreviousDeclaration())
+ First = First->getPreviousDeclaration();
+
+ if (First->CommonOrPrev.isNull()) {
+ // FIXME: Allocate with the ASTContext
+ First->CommonOrPrev = new Common;
+ }
+ return First->CommonOrPrev.get<Common*>();
+}
+
//===----------------------------------------------------------------------===//
// ClassTemplateDecl Implementation
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index fce88cc0da28..482e1062d88c 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -41,8 +41,7 @@ CharacterLiteral* CharacterLiteral::Clone(ASTContext &C) const {
}
FloatingLiteral* FloatingLiteral::Clone(ASTContext &C) const {
- bool exact = IsExact;
- return new (C) FloatingLiteral(Value, &exact, getType(), Loc);
+ return new (C) FloatingLiteral(Value, IsExact, getType(), Loc);
}
ImaginaryLiteral* ImaginaryLiteral::Clone(ASTContext &C) const {
@@ -456,7 +455,7 @@ Stmt *BlockExpr::getBody() {
/// with location to warn on and the source range[s] to report with the
/// warning.
bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
- SourceRange &R2, ASTContext &Context) const {
+ SourceRange &R2) const {
// Don't warn if the expr is type dependent. The type could end up
// instantiating to void.
if (isTypeDependent())
@@ -469,7 +468,7 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
return true;
case ParenExprClass:
return cast<ParenExpr>(this)->getSubExpr()->
- isUnusedResultAWarning(Loc, R1, R2, Context);
+ isUnusedResultAWarning(Loc, R1, R2);
case UnaryOperatorClass: {
const UnaryOperator *UO = cast<UnaryOperator>(this);
@@ -492,7 +491,7 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
return false;
break;
case UnaryOperator::Extension:
- return UO->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Context);
+ return UO->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2);
}
Loc = UO->getOperatorLoc();
R1 = UO->getSubExpr()->getSourceRange();
@@ -502,8 +501,8 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
const BinaryOperator *BO = cast<BinaryOperator>(this);
// Consider comma to have side effects if the LHS or RHS does.
if (BO->getOpcode() == BinaryOperator::Comma)
- return BO->getRHS()->isUnusedResultAWarning(Loc, R1, R2, Context) ||
- BO->getLHS()->isUnusedResultAWarning(Loc, R1, R2, Context);
+ return BO->getRHS()->isUnusedResultAWarning(Loc, R1, R2) ||
+ BO->getLHS()->isUnusedResultAWarning(Loc, R1, R2);
if (BO->isAssignmentOp())
return false;
@@ -520,9 +519,9 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
// warning, warn about them.
const ConditionalOperator *Exp = cast<ConditionalOperator>(this);
if (Exp->getLHS() &&
- Exp->getLHS()->isUnusedResultAWarning(Loc, R1, R2, Context))
+ Exp->getLHS()->isUnusedResultAWarning(Loc, R1, R2))
return true;
- return Exp->getRHS()->isUnusedResultAWarning(Loc, R1, R2, Context);
+ return Exp->getRHS()->isUnusedResultAWarning(Loc, R1, R2);
}
case MemberExprClass:
@@ -555,8 +554,8 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
// If the callee has attribute pure, const, or warn_unused_result, warn
// about it. void foo() { strlen("bar"); } should warn.
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CalleeDRE->getDecl()))
- if (FD->getAttr<WarnUnusedResultAttr>(Context) ||
- FD->getAttr<PureAttr>(Context) || FD->getAttr<ConstAttr>(Context)) {
+ if (FD->getAttr<WarnUnusedResultAttr>() ||
+ FD->getAttr<PureAttr>() || FD->getAttr<ConstAttr>()) {
Loc = CE->getCallee()->getLocStart();
R1 = CE->getCallee()->getSourceRange();
@@ -579,7 +578,7 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
const CompoundStmt *CS = cast<StmtExpr>(this)->getSubStmt();
if (!CS->body_empty())
if (const Expr *E = dyn_cast<Expr>(CS->body_back()))
- return E->isUnusedResultAWarning(Loc, R1, R2, Context);
+ return E->isUnusedResultAWarning(Loc, R1, R2);
Loc = cast<StmtExpr>(this)->getLParenLoc();
R1 = getSourceRange();
@@ -590,7 +589,7 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
// the cast is unused.
if (getType()->isVoidType())
return cast<CastExpr>(this)->getSubExpr()
- ->isUnusedResultAWarning(Loc, R1, R2, Context);
+ ->isUnusedResultAWarning(Loc, R1, R2);
Loc = cast<CStyleCastExpr>(this)->getLParenLoc();
R1 = cast<CStyleCastExpr>(this)->getSubExpr()->getSourceRange();
return true;
@@ -599,7 +598,7 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
// the cast is unused.
if (getType()->isVoidType())
return cast<CastExpr>(this)->getSubExpr()
- ->isUnusedResultAWarning(Loc, R1, R2, Context);
+ ->isUnusedResultAWarning(Loc, R1, R2);
Loc = cast<CXXFunctionalCastExpr>(this)->getTypeBeginLoc();
R1 = cast<CXXFunctionalCastExpr>(this)->getSubExpr()->getSourceRange();
return true;
@@ -607,11 +606,11 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
case ImplicitCastExprClass:
// Check the operand, since implicit casts are inserted by Sema
return cast<ImplicitCastExpr>(this)
- ->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Context);
+ ->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2);
case CXXDefaultArgExprClass:
return cast<CXXDefaultArgExpr>(this)
- ->getExpr()->isUnusedResultAWarning(Loc, R1, R2, Context);
+ ->getExpr()->isUnusedResultAWarning(Loc, R1, R2);
case CXXNewExprClass:
// FIXME: In theory, there might be new expressions that don't have side
@@ -620,7 +619,7 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
return false;
case CXXExprWithTemporariesClass:
return cast<CXXExprWithTemporaries>(this)
- ->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Context);
+ ->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2);
}
}
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 18c0f77ab29e..399c30255a8f 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -13,6 +13,7 @@
#include "clang/Basic/IdentifierTable.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
#include "clang/AST/ExprCXX.h"
using namespace clang;
@@ -153,6 +154,65 @@ StmtIterator UnresolvedDeclRefExpr::child_end() {
return child_iterator();
}
+TemplateIdRefExpr::TemplateIdRefExpr(QualType T,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ TemplateName Template,
+ SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc,
+ const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs,
+ SourceLocation RAngleLoc)
+ : Expr(TemplateIdRefExprClass, T,
+ (Template.isDependent() ||
+ TemplateSpecializationType::anyDependentTemplateArguments(
+ TemplateArgs, NumTemplateArgs)),
+ (Template.isDependent() ||
+ TemplateSpecializationType::anyDependentTemplateArguments(
+ TemplateArgs, NumTemplateArgs))),
+ Qualifier(Qualifier), QualifierRange(QualifierRange), Template(Template),
+ TemplateNameLoc(TemplateNameLoc), LAngleLoc(LAngleLoc),
+ RAngleLoc(RAngleLoc), NumTemplateArgs(NumTemplateArgs)
+
+{
+ TemplateArgument *StoredTemplateArgs
+ = reinterpret_cast<TemplateArgument *> (this+1);
+ for (unsigned I = 0; I != NumTemplateArgs; ++I)
+ new (StoredTemplateArgs + I) TemplateArgument(TemplateArgs[I]);
+}
+
+TemplateIdRefExpr *
+TemplateIdRefExpr::Create(ASTContext &Context, QualType T,
+ NestedNameSpecifier *Qualifier,
+ SourceRange QualifierRange,
+ TemplateName Template, SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc,
+ const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs, SourceLocation RAngleLoc) {
+ void *Mem = Context.Allocate(sizeof(TemplateIdRefExpr) +
+ sizeof(TemplateArgument) * NumTemplateArgs);
+ return new (Mem) TemplateIdRefExpr(T, Qualifier, QualifierRange, Template,
+ TemplateNameLoc, LAngleLoc, TemplateArgs,
+ NumTemplateArgs, RAngleLoc);
+}
+
+void TemplateIdRefExpr::Destroy(ASTContext &Context) {
+ const TemplateArgument *TemplateArgs = getTemplateArgs();
+ for (unsigned I = 0; I != NumTemplateArgs; ++I)
+ if (Expr *E = TemplateArgs[I].getAsExpr())
+ E->Destroy(Context);
+}
+
+Stmt::child_iterator TemplateIdRefExpr::child_begin() {
+ // FIXME: Walk the expressions in the template arguments (?)
+ return Stmt::child_iterator();
+}
+
+Stmt::child_iterator TemplateIdRefExpr::child_end() {
+ // FIXME: Walk the expressions in the template arguments (?)
+ return Stmt::child_iterator();
+}
+
bool UnaryTypeTraitExpr::EvaluateTrait() const {
switch(UTT) {
default: assert(false && "Unknown type trait or not implemented");
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 9d765924e02a..eb6b5b725ff5 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -242,8 +242,8 @@ APValue LValueExprEvaluator::VisitMemberExpr(MemberExpr *E) {
// FIXME: This is linear time.
unsigned i = 0;
- for (RecordDecl::field_iterator Field = RD->field_begin(Info.Ctx),
- FieldEnd = RD->field_end(Info.Ctx);
+ for (RecordDecl::field_iterator Field = RD->field_begin(),
+ FieldEnd = RD->field_end();
Field != FieldEnd; (void)++Field, ++i) {
if (*Field == FD)
break;
@@ -485,6 +485,11 @@ static bool EvaluateVector(const Expr* E, APValue& Result, EvalInfo &Info) {
}
APValue VectorExprEvaluator::VisitCastExpr(const CastExpr* E) {
+ const VectorType *VTy = E->getType()->getAsVectorType();
+ QualType EltTy = VTy->getElementType();
+ unsigned NElts = VTy->getNumElements();
+ unsigned EltWidth = Info.Ctx.getTypeSize(EltTy);
+
const Expr* SE = E->getSubExpr();
QualType SETy = SE->getType();
APValue Result = APValue();
@@ -494,20 +499,62 @@ APValue VectorExprEvaluator::VisitCastExpr(const CastExpr* E) {
return this->Visit(const_cast<Expr*>(SE));
} else if (SETy->isIntegerType()) {
APSInt IntResult;
- if (EvaluateInteger(SE, IntResult, Info))
- Result = APValue(IntResult);
+ if (!EvaluateInteger(SE, IntResult, Info))
+ return APValue();
+ Result = APValue(IntResult);
} else if (SETy->isRealFloatingType()) {
APFloat F(0.0);
- if (EvaluateFloat(SE, F, Info))
- Result = APValue(F);
+ if (!EvaluateFloat(SE, F, Info))
+ return APValue();
+ Result = APValue(F);
+ } else
+ return APValue();
+
+ // For casts of a scalar to ExtVector, convert the scalar to the element type
+ // and splat it to all elements.
+ if (E->getType()->isExtVectorType()) {
+ if (EltTy->isIntegerType() && Result.isInt())
+ Result = APValue(HandleIntToIntCast(EltTy, SETy, Result.getInt(),
+ Info.Ctx));
+ else if (EltTy->isIntegerType())
+ Result = APValue(HandleFloatToIntCast(EltTy, SETy, Result.getFloat(),
+ Info.Ctx));
+ else if (EltTy->isRealFloatingType() && Result.isInt())
+ Result = APValue(HandleIntToFloatCast(EltTy, SETy, Result.getInt(),
+ Info.Ctx));
+ else if (EltTy->isRealFloatingType())
+ Result = APValue(HandleFloatToFloatCast(EltTy, SETy, Result.getFloat(),
+ Info.Ctx));
+ else
+ return APValue();
+
+ // Splat and create vector APValue.
+ llvm::SmallVector<APValue, 4> Elts(NElts, Result);
+ return APValue(&Elts[0], Elts.size());
}
- if (Result.isInt() || Result.isFloat()) {
- unsigned NumElts = E->getType()->getAsVectorType()->getNumElements();
- llvm::SmallVector<APValue, 4> Elts(NumElts, Result);
- Result = APValue(&Elts[0], Elts.size());
+ // For casts of a scalar to regular gcc-style vector type, bitcast the scalar
+ // to the vector. To construct the APValue vector initializer, bitcast the
+ // initializing value to an APInt, and shift out the bits pertaining to each
+ // element.
+ APSInt Init;
+ Init = Result.isInt() ? Result.getInt() : Result.getFloat().bitcastToAPInt();
+
+ llvm::SmallVector<APValue, 4> Elts;
+ for (unsigned i = 0; i != NElts; ++i) {
+ APSInt Tmp = Init;
+ Tmp.extOrTrunc(EltWidth);
+
+ if (EltTy->isIntegerType())
+ Elts.push_back(APValue(Tmp));
+ else if (EltTy->isRealFloatingType())
+ Elts.push_back(APValue(APFloat(Tmp)));
+ else
+ return APValue();
+
+ Init >>= EltWidth;
}
- return Result;
+ return APValue(&Elts[0], Elts.size());
}
APValue
diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp
index 09522a20863c..90ec4d33fdfe 100644
--- a/lib/AST/NestedNameSpecifier.cpp
+++ b/lib/AST/NestedNameSpecifier.cpp
@@ -153,8 +153,6 @@ void NestedNameSpecifier::Destroy(ASTContext &Context) {
Context.Deallocate((void *)this);
}
-void NestedNameSpecifier::dump() {
- PrintingPolicy Policy;
- Policy.CPlusPlus = true;
- print(llvm::errs(), Policy);
+void NestedNameSpecifier::dump(const LangOptions &LO) {
+ print(llvm::errs(), PrintingPolicy(LO));
}
diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp
index b24e912582d5..bc096bf0d9f3 100644
--- a/lib/AST/StmtDumper.cpp
+++ b/lib/AST/StmtDumper.cpp
@@ -41,7 +41,6 @@ namespace {
const char *LastLocFilename;
unsigned LastLocLine;
- PrintingPolicy Policy;
public:
StmtDumper(SourceManager *sm, FILE *f, unsigned maxDepth)
: SM(sm), F(f), IndentLevel(0-1), MaxDepth(maxDepth) {
@@ -226,7 +225,8 @@ void StmtDumper::DumpDeclarator(Decl *D) {
}
std::string Name = VD->getNameAsString();
- VD->getType().getAsStringInternal(Name, Policy);
+ VD->getType().getAsStringInternal(Name,
+ PrintingPolicy(VD->getASTContext().getLangOptions()));
fprintf(F, "%s", Name.c_str());
// If this is a vardecl with an initializer, emit it.
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index b300940824de..fec17fb22352 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -35,7 +35,7 @@ namespace {
public:
StmtPrinter(llvm::raw_ostream &os, ASTContext &C, PrinterHelper* helper,
- const PrintingPolicy &Policy = PrintingPolicy(),
+ const PrintingPolicy &Policy,
unsigned Indentation = 0)
: OS(os), Context(C), IndentLevel(Indentation), Helper(helper),
Policy(Policy) {}
@@ -114,7 +114,7 @@ void StmtPrinter::PrintRawCompoundStmt(CompoundStmt *Node) {
}
void StmtPrinter::PrintRawDecl(Decl *D) {
- D->print(OS, Context, Policy, IndentLevel);
+ D->print(OS, Policy, IndentLevel);
}
void StmtPrinter::PrintRawDeclStmt(DeclStmt *S) {
@@ -123,8 +123,7 @@ void StmtPrinter::PrintRawDeclStmt(DeclStmt *S) {
for ( ; Begin != End; ++Begin)
Decls.push_back(*Begin);
- Decl::printGroup(Decls.data(), Decls.size(), OS, Context, Policy,
- IndentLevel);
+ Decl::printGroup(Decls.data(), Decls.size(), OS, Policy, IndentLevel);
}
void StmtPrinter::VisitNullStmt(NullStmt *Node) {
@@ -491,6 +490,18 @@ void StmtPrinter::VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *Node) {
OS << Node->getDeclName().getAsString();
}
+void StmtPrinter::VisitTemplateIdRefExpr(TemplateIdRefExpr *Node) {
+ if (Node->getQualifier())
+ Node->getQualifier()->print(OS, Policy);
+ Node->getTemplateName().print(OS, Policy, true);
+ OS << '<';
+ OS << TemplateSpecializationType::PrintTemplateArgumentList(
+ Node->getTemplateArgs(),
+ Node->getNumTemplateArgs(),
+ Policy);
+ OS << '>';
+}
+
void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
if (Node->getBase()) {
PrintExpr(Node->getBase());
@@ -861,7 +872,7 @@ void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
}
void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
- if (Policy.CPlusPlus)
+ if (Policy.LangOpts.CPlusPlus)
OS << "/*implicit*/" << Node->getType().getAsString(Policy) << "()";
else {
OS << "/*implicit*/(" << Node->getType().getAsString(Policy) << ")";
@@ -1216,7 +1227,8 @@ void StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) {
//===----------------------------------------------------------------------===//
void Stmt::dumpPretty(ASTContext& Context) const {
- printPretty(llvm::errs(), Context, 0, PrintingPolicy());
+ printPretty(llvm::errs(), Context, 0,
+ PrintingPolicy(Context.getLangOptions()));
}
void Stmt::printPretty(llvm::raw_ostream &OS, ASTContext& Context,
diff --git a/lib/AST/TemplateName.cpp b/lib/AST/TemplateName.cpp
index 3613da77b342..5b671c111fbf 100644
--- a/lib/AST/TemplateName.cpp
+++ b/lib/AST/TemplateName.cpp
@@ -15,6 +15,7 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/PrettyPrinter.h"
+#include "clang/Basic/LangOptions.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
@@ -59,7 +60,8 @@ TemplateName::print(llvm::raw_ostream &OS, const PrintingPolicy &Policy,
}
void TemplateName::dump() const {
- PrintingPolicy Policy;
- Policy.CPlusPlus = true;
- print(llvm::errs(), Policy);
+ LangOptions LO; // FIXME!
+ LO.CPlusPlus = true;
+ LO.Bool = true;
+ print(llvm::errs(), PrintingPolicy(LO));
}
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 41536612fec8..4e061a9fbe62 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -185,6 +185,12 @@ bool Type::isStructureType() const {
return RT->getDecl()->isStruct();
return false;
}
+bool Type::isVoidPointerType() const {
+ if (const PointerType *PT = getAsPointerType())
+ return PT->getPointeeType()->isVoidType();
+ return false;
+}
+
bool Type::isUnionType() const {
if (const RecordType *RT = getAsRecordType())
return RT->getDecl()->isUnion();
@@ -938,11 +944,11 @@ bool Type::isSpecifierType() const {
}
}
-const char *BuiltinType::getName(bool CPlusPlus) const {
+const char *BuiltinType::getName(const LangOptions &LO) const {
switch (getKind()) {
default: assert(0 && "Unknown builtin type!");
case Void: return "void";
- case Bool: return CPlusPlus? "bool" : "_Bool";
+ case Bool: return LO.Bool ? "bool" : "_Bool";
case Char_S: return "char";
case Char_U: return "char";
case SChar: return "signed char";
@@ -1160,9 +1166,9 @@ TemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
//===----------------------------------------------------------------------===//
void QualType::dump(const char *msg) const {
- PrintingPolicy Policy;
std::string R = "identifier";
- getAsStringInternal(R, Policy);
+ LangOptions LO;
+ getAsStringInternal(R, PrintingPolicy(LO));
if (msg)
fprintf(stderr, "%s: %s\n", msg, R.c_str());
else
@@ -1174,7 +1180,8 @@ void QualType::dump() const {
void Type::dump() const {
std::string S = "identifier";
- getAsStringInternal(S, PrintingPolicy());
+ LangOptions LO;
+ getAsStringInternal(S, PrintingPolicy(LO));
fprintf(stderr, "%s\n", S.c_str());
}
@@ -1193,7 +1200,8 @@ static void AppendTypeQualList(std::string &S, unsigned TypeQuals) {
std::string QualType::getAsString() const {
std::string S;
- getAsStringInternal(S, PrintingPolicy());
+ LangOptions LO;
+ getAsStringInternal(S, PrintingPolicy(LO));
return S;
}
@@ -1224,11 +1232,11 @@ QualType::getAsStringInternal(std::string &S,
void BuiltinType::getAsStringInternal(std::string &S,
const PrintingPolicy &Policy) const {
if (S.empty()) {
- S = getName(Policy.CPlusPlus);
+ S = getName(Policy.LangOpts);
} else {
// Prefix the basic type, e.g. 'int X'.
S = ' ' + S;
- S = getName(Policy.CPlusPlus) + S;
+ S = getName(Policy.LangOpts) + S;
}
}
@@ -1470,7 +1478,7 @@ void FunctionProtoType::getAsStringInternal(std::string &S, const PrintingPolicy
if (getNumArgs())
S += ", ";
S += "...";
- } else if (getNumArgs() == 0 && !Policy.CPlusPlus) {
+ } else if (getNumArgs() == 0 && !Policy.LangOpts.CPlusPlus) {
// Do not emit int() if we have a proto, emit 'int(void)'.
S += "void";
}
diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp
index 8fbce528fa9a..19d641ee9753 100644
--- a/lib/Analysis/BasicStore.cpp
+++ b/lib/Analysis/BasicStore.cpp
@@ -198,7 +198,7 @@ SVal BasicStoreManager::getLValueElement(const GRState *state,
return Base;
Loc BaseL = cast<Loc>(Base);
- const TypedRegion* BaseR = 0;
+ const MemRegion* BaseR = 0;
switch(BaseL.getSubKind()) {
case loc::GotoLabelKind:
@@ -216,17 +216,11 @@ SVal BasicStoreManager::getLValueElement(const GRState *state,
return Base;
}
-
- if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) {
- BaseR = TR;
+ if (isa<TypedRegion>(R) || isa<SymbolicRegion>(R)) {
+ BaseR = R;
break;
}
- if (const SymbolicRegion* SR = dyn_cast<SymbolicRegion>(R)) {
- SymbolRef Sym = SR->getSymbol();
- BaseR = MRMgr.getTypedViewRegion(Sym->getType(getContext()), SR);
- }
-
break;
}
@@ -242,9 +236,10 @@ SVal BasicStoreManager::getLValueElement(const GRState *state,
return Base;
}
- if (BaseR)
+ if (BaseR) {
return ValMgr.makeLoc(MRMgr.getElementRegion(elementType, UnknownVal(),
BaseR, getContext()));
+ }
else
return UnknownVal();
}
@@ -319,54 +314,50 @@ SVal BasicStoreManager::Retrieve(const GRState *state, Loc loc, QualType T) {
}
Store BasicStoreManager::BindInternal(Store store, Loc loc, SVal V) {
- switch (loc.getSubKind()) {
- case loc::MemRegionKind: {
- const MemRegion* R = cast<loc::MemRegionVal>(loc).getRegion();
- ASTContext &C = StateMgr.getContext();
+ if (isa<loc::ConcreteInt>(loc))
+ return store;
+
+ const MemRegion* R = cast<loc::MemRegionVal>(loc).getRegion();
+ ASTContext &C = StateMgr.getContext();
- // Special case: handle store of pointer values (Loc) to pointers via
- // a cast to intXX_t*, void*, etc. This is needed to handle
- // OSCompareAndSwap32Barrier/OSCompareAndSwap64Barrier.
- if (isa<Loc>(V) || isa<nonloc::LocAsInteger>(V))
- if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
- // FIXME: Should check for index 0.
- QualType T = ER->getLocationType(C);
+ // Special case: handle store of pointer values (Loc) to pointers via
+ // a cast to intXX_t*, void*, etc. This is needed to handle
+ // OSCompareAndSwap32Barrier/OSCompareAndSwap64Barrier.
+ if (isa<Loc>(V) || isa<nonloc::LocAsInteger>(V))
+ if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
+ // FIXME: Should check for index 0.
+ QualType T = ER->getLocationType(C);
- if (isHigherOrderRawPtr(T, C))
- R = ER->getSuperRegion();
- }
+ if (isHigherOrderRawPtr(T, C))
+ R = ER->getSuperRegion();
+ }
- if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
- return store;
+ if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
+ return store;
- // We only track bindings to self.ivar.
- if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R))
- if (IVR->getSuperRegion() != SelfRegion)
- return store;
+ // We only track bindings to self.ivar.
+ if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R))
+ if (IVR->getSuperRegion() != SelfRegion)
+ return store;
- if (nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(&V)) {
- // Only convert 'V' to a location iff the underlying region type
- // is a location as well.
- // FIXME: We are allowing a store of an arbitrary location to
- // a pointer. We may wish to flag a type error here if the types
- // are incompatible. This may also cause lots of breakage
- // elsewhere. Food for thought.
- if (const TypedRegion *TyR = dyn_cast<TypedRegion>(R)) {
- if (TyR->isBoundable() &&
- Loc::IsLocType(TyR->getValueType(C)))
- V = X->getLoc();
- }
- }
-
- BindingsTy B = GetBindings(store);
- return V.isUnknown()
- ? VBFactory.Remove(B, R).getRoot()
- : VBFactory.Add(B, R, V).getRoot();
+ if (nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(&V)) {
+ // Only convert 'V' to a location iff the underlying region type
+ // is a location as well.
+ // FIXME: We are allowing a store of an arbitrary location to
+ // a pointer. We may wish to flag a type error here if the types
+ // are incompatible. This may also cause lots of breakage
+ // elsewhere. Food for thought.
+ if (const TypedRegion *TyR = dyn_cast<TypedRegion>(R)) {
+ if (TyR->isBoundable() &&
+ Loc::IsLocType(TyR->getValueType(C)))
+ V = X->getLoc();
}
- default:
- assert ("SetSVal for given Loc type not yet implemented.");
- return store;
}
+
+ BindingsTy B = GetBindings(store);
+ return V.isUnknown()
+ ? VBFactory.Remove(B, R).getRoot()
+ : VBFactory.Add(B, R, V).getRoot();
}
Store BasicStoreManager::Remove(Store store, Loc loc) {
@@ -521,7 +512,7 @@ Store BasicStoreManager::getInitialStore() {
// Scan the method for ivar references. While this requires an
// entire AST scan, the cost should not be high in practice.
- St = scanForIvars(MD->getBody(getContext()), PD, St);
+ St = scanForIvars(MD->getBody(), PD, St);
}
}
}
@@ -537,10 +528,9 @@ Store BasicStoreManager::getInitialStore() {
// Initialize globals and parameters to symbolic values.
// Initialize local variables to undefined.
const MemRegion *R = ValMgr.getRegionManager().getVarRegion(VD);
- SVal X = (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD) ||
- isa<ImplicitParamDecl>(VD))
- ? ValMgr.getRegionValueSymbolVal(R)
- : UndefinedVal();
+ SVal X = R->hasGlobalsOrParametersStorage()
+ ? ValMgr.getRegionValueSymbolVal(R)
+ : UndefinedVal();
St = BindInternal(St, ValMgr.makeLoc(R), X);
}
@@ -594,7 +584,7 @@ Store BasicStoreManager::BindDeclInternal(Store store, const VarDecl* VD,
} else {
// Process local scalar variables.
QualType T = VD->getType();
- if (Loc::IsLocType(T) || T->isIntegerType()) {
+ if (ValMgr.getSymbolManager().canSymbolicate(T)) {
SVal V = InitVal ? *InitVal : UndefinedVal();
store = BindInternal(store, getLoc(VD), V);
}
diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp
index 38ea458a6599..3db96ca9eacb 100644
--- a/lib/Analysis/BugReporter.cpp
+++ b/lib/Analysis/BugReporter.cpp
@@ -146,7 +146,7 @@ public:
ParentMap& getParentMap() {
if (PM.get() == 0)
- PM.reset(new ParentMap(getCodeDecl().getBody(getASTContext())));
+ PM.reset(new ParentMap(getCodeDecl().getBody()));
return *PM.get();
}
@@ -182,8 +182,7 @@ PathDiagnosticBuilder::ExecutionContinues(const ExplodedNode<GRState>* N) {
if (Stmt *S = GetNextStmt(N))
return PathDiagnosticLocation(S, getSourceManager());
- return FullSourceLoc(getCodeDecl().getBodyRBrace(getASTContext()),
- getSourceManager());
+ return FullSourceLoc(getCodeDecl().getBodyRBrace(), getSourceManager());
}
PathDiagnosticLocation
@@ -893,7 +892,7 @@ public:
// statement (if it doesn't already exist).
// FIXME: Should handle CXXTryStmt if analyser starts supporting C++.
if (const CompoundStmt *CS =
- PDB.getCodeDecl().getCompoundBody(PDB.getASTContext()))
+ PDB.getCodeDecl().getCompoundBody())
if (!CS->body_empty()) {
SourceLocation Loc = (*CS->body_begin())->getLocStart();
rawAddEdge(PathDiagnosticLocation(Loc, PDB.getSourceManager()));
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index f4a28e0c19fd..3cca482633ca 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -156,13 +156,13 @@ static bool followsFundamentalRule(Selector S) {
}
static const ObjCMethodDecl*
-ResolveToInterfaceMethodDecl(const ObjCMethodDecl *MD, ASTContext &Context) {
+ResolveToInterfaceMethodDecl(const ObjCMethodDecl *MD) {
ObjCInterfaceDecl *ID =
const_cast<ObjCInterfaceDecl*>(MD->getClassInterface());
return MD->isInstanceMethod()
- ? ID->lookupInstanceMethod(Context, MD->getSelector())
- : ID->lookupClassMethod(Context, MD->getSelector());
+ ? ID->lookupInstanceMethod(MD->getSelector())
+ : ID->lookupClassMethod(MD->getSelector());
}
namespace {
@@ -827,8 +827,7 @@ public:
QualType ResultTy = MD->getResultType();
// Resolve the method decl last.
- if (const ObjCMethodDecl *InterfaceMD =
- ResolveToInterfaceMethodDecl(MD, Ctx))
+ if (const ObjCMethodDecl *InterfaceMD = ResolveToInterfaceMethodDecl(MD))
MD = InterfaceMD;
if (MD->isInstanceMethod())
@@ -1248,15 +1247,15 @@ RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary &Summ,
// Determine if there is a special return effect for this method.
if (isTrackedObjCObjectType(RetTy)) {
- if (FD->getAttr<NSReturnsRetainedAttr>(Ctx)) {
+ if (FD->getAttr<NSReturnsRetainedAttr>()) {
Summ.setRetEffect(ObjCAllocRetE);
}
- else if (FD->getAttr<CFReturnsRetainedAttr>(Ctx)) {
+ else if (FD->getAttr<CFReturnsRetainedAttr>()) {
Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
}
}
else if (RetTy->getAsPointerType()) {
- if (FD->getAttr<CFReturnsRetainedAttr>(Ctx)) {
+ if (FD->getAttr<CFReturnsRetainedAttr>()) {
Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
}
}
@@ -1270,10 +1269,10 @@ RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary &Summ,
// Determine if there is a special return effect for this method.
if (isTrackedObjCObjectType(MD->getResultType())) {
- if (MD->getAttr<NSReturnsRetainedAttr>(Ctx)) {
+ if (MD->getAttr<NSReturnsRetainedAttr>()) {
Summ.setRetEffect(ObjCAllocRetE);
}
- else if (MD->getAttr<CFReturnsRetainedAttr>(Ctx)) {
+ else if (MD->getAttr<CFReturnsRetainedAttr>()) {
Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));
}
}
@@ -2632,7 +2631,7 @@ CFRefLeakReport::getEndPath(BugReporterContext& BRC,
if (!L.isValid()) {
const Decl &D = BRC.getCodeDecl();
- L = PathDiagnosticLocation(D.getBodyRBrace(BRC.getASTContext()), SMgr);
+ L = PathDiagnosticLocation(D.getBodyRBrace(), SMgr);
}
std::string sbuf;
@@ -2796,7 +2795,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
// to identify conjured symbols by an expression pair: the enclosing
// expression (the context) and the expression itself. This should
// disambiguate conjured symbols.
-
+ unsigned Count = Builder.getCurrentBlockCount();
const TypedRegion* R = dyn_cast<TypedRegion>(MR->getRegion());
if (R) {
@@ -2833,7 +2832,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
if (R->isBoundable()) {
// Set the value of the variable to be a conjured symbol.
- unsigned Count = Builder.getCurrentBlockCount();
+
QualType T = R->getValueType(Ctx);
if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())){
@@ -2857,20 +2856,31 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
state->getStateManager().getRegionManager();
// Iterate through the fields and construct new symbols.
- for (RecordDecl::field_iterator FI=RD->field_begin(Ctx),
- FE=RD->field_end(Ctx); FI!=FE; ++FI) {
+ for (RecordDecl::field_iterator FI=RD->field_begin(),
+ FE=RD->field_end(); FI!=FE; ++FI) {
// For now just handle scalar fields.
FieldDecl *FD = *FI;
QualType FT = FD->getType();
-
+ const FieldRegion* FR = MRMgr.getFieldRegion(FD, R);
+
if (Loc::IsLocType(FT) ||
(FT->isIntegerType() && FT->isScalarType())) {
- const FieldRegion* FR = MRMgr.getFieldRegion(FD, R);
-
SVal V = ValMgr.getConjuredSymbolVal(*I, FT, Count);
state = state->bindLoc(ValMgr.makeLoc(FR), V);
- }
+ }
+ else if (FT->isStructureType()) {
+ // set the default value of the struct field to conjured
+ // symbol. Note that the type of the symbol is irrelavant.
+ // We cannot use the type of the struct otherwise ValMgr won't
+ // give us the conjured symbol.
+ StoreManager& StoreMgr =
+ Eng.getStateManager().getStoreManager();
+ SVal V = ValMgr.getConjuredSymbolVal(*I,
+ Eng.getContext().IntTy,
+ Count);
+ state = StoreMgr.setDefaultValue(state, FR, V);
+ }
}
} else if (const ArrayType *AT = Ctx.getAsArrayType(T)) {
// Set the default value of the array to conjured symbol.
@@ -2884,6 +2894,15 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
}
}
}
+ else if (isa<AllocaRegion>(MR->getRegion())) {
+ // Invalidate the alloca region by setting its default value to
+ // conjured symbol. The type of the symbol is irrelavant.
+ SVal V = ValMgr.getConjuredSymbolVal(*I, Eng.getContext().IntTy,
+ Count);
+ StoreManager& StoreMgr =
+ Eng.getStateManager().getStoreManager();
+ state = StoreMgr.setDefaultValue(state, MR->getRegion(), V);
+ }
else
state = state->bindLoc(*MR, UnknownVal());
}
diff --git a/lib/Analysis/CheckDeadStores.cpp b/lib/Analysis/CheckDeadStores.cpp
index 0f61a5ee916a..69433d6396a5 100644
--- a/lib/Analysis/CheckDeadStores.cpp
+++ b/lib/Analysis/CheckDeadStores.cpp
@@ -85,7 +85,7 @@ public:
const LiveVariables::AnalysisDataTy& AD,
const LiveVariables::ValTy& Live) {
- if (VD->hasLocalStorage() && !Live(VD, AD) && !VD->getAttr<UnusedAttr>(Ctx))
+ if (VD->hasLocalStorage() && !Live(VD, AD) && !VD->getAttr<UnusedAttr>())
Report(VD, dsk, Ex->getSourceRange().getBegin(),
Val->getSourceRange());
}
@@ -190,7 +190,7 @@ public:
// A dead initialization is a variable that is dead after it
// is initialized. We don't flag warnings for those variables
// marked 'unused'.
- if (!Live(V, AD) && V->getAttr<UnusedAttr>(Ctx) == 0) {
+ if (!Live(V, AD) && V->getAttr<UnusedAttr>() == 0) {
// Special case: check for initializations with constants.
//
// e.g. : int x = 0;
diff --git a/lib/Analysis/CheckObjCDealloc.cpp b/lib/Analysis/CheckObjCDealloc.cpp
index 2ba7d868e90b..a14ae265128b 100644
--- a/lib/Analysis/CheckObjCDealloc.cpp
+++ b/lib/Analysis/CheckObjCDealloc.cpp
@@ -109,7 +109,7 @@ void clang::CheckObjCDealloc(ObjCImplementationDecl* D,
QualType T = ID->getType();
if (!Ctx.isObjCObjectPointerType(T) ||
- ID->getAttr<IBOutletAttr>(Ctx)) // Skip IBOutlets.
+ ID->getAttr<IBOutletAttr>()) // Skip IBOutlets.
continue;
containsPointerIvar = true;
@@ -147,8 +147,8 @@ void clang::CheckObjCDealloc(ObjCImplementationDecl* D,
ObjCMethodDecl* MD = 0;
// Scan the instance methods for "dealloc".
- for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(Ctx),
- E = D->instmeth_end(Ctx); I!=E; ++I) {
+ for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(),
+ E = D->instmeth_end(); I!=E; ++I) {
if ((*I)->getSelector() == S) {
MD = *I;
@@ -172,7 +172,7 @@ void clang::CheckObjCDealloc(ObjCImplementationDecl* D,
}
// dealloc found. Scan for missing [super dealloc].
- if (MD->getBody(Ctx) && !scan_dealloc(MD->getBody(Ctx), S)) {
+ if (MD->getBody() && !scan_dealloc(MD->getBody(), S)) {
const char* name = LOpts.getGCMode() == LangOptions::NonGC
? "missing [super dealloc]"
@@ -198,8 +198,8 @@ void clang::CheckObjCDealloc(ObjCImplementationDecl* D,
// Scan for missing and extra releases of ivars used by implementations
// of synthesized properties
- for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(Ctx),
- E = D->propimpl_end(Ctx); I!=E; ++I) {
+ for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(),
+ E = D->propimpl_end(); I!=E; ++I) {
// We can only check the synthesized properties
if((*I)->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize)
@@ -223,7 +223,7 @@ void clang::CheckObjCDealloc(ObjCImplementationDecl* D,
// ivar must be released if and only if the kind of setter was not 'assign'
bool requiresRelease = PD->getSetterKind() != ObjCPropertyDecl::Assign;
- if(scan_ivar_release(MD->getBody(Ctx), ID, PD, RS, SelfII, Ctx)
+ if(scan_ivar_release(MD->getBody(), ID, PD, RS, SelfII, Ctx)
!= requiresRelease) {
const char *name;
const char* category = "Memory (Core Foundation/Objective-C)";
diff --git a/lib/Analysis/CheckObjCInstMethSignature.cpp b/lib/Analysis/CheckObjCInstMethSignature.cpp
index 9fec7c1dc111..28814867bd58 100644
--- a/lib/Analysis/CheckObjCInstMethSignature.cpp
+++ b/lib/Analysis/CheckObjCInstMethSignature.cpp
@@ -86,8 +86,8 @@ void clang::CheckObjCInstMethSignature(ObjCImplementationDecl* ID,
MapTy IMeths;
unsigned NumMethods = 0;
- for (ObjCImplementationDecl::instmeth_iterator I=ID->instmeth_begin(Ctx),
- E=ID->instmeth_end(Ctx); I!=E; ++I) {
+ for (ObjCImplementationDecl::instmeth_iterator I=ID->instmeth_begin(),
+ E=ID->instmeth_end(); I!=E; ++I) {
ObjCMethodDecl* M = *I;
IMeths[M->getSelector()] = M;
@@ -97,8 +97,8 @@ void clang::CheckObjCInstMethSignature(ObjCImplementationDecl* ID,
// Now recurse the class hierarchy chain looking for methods with the
// same signatures.
while (C && NumMethods) {
- for (ObjCInterfaceDecl::instmeth_iterator I=C->instmeth_begin(Ctx),
- E=C->instmeth_end(Ctx); I!=E; ++I) {
+ for (ObjCInterfaceDecl::instmeth_iterator I=C->instmeth_begin(),
+ E=C->instmeth_end(); I!=E; ++I) {
ObjCMethodDecl* M = *I;
Selector S = M->getSelector();
diff --git a/lib/Analysis/CheckObjCUnusedIVars.cpp b/lib/Analysis/CheckObjCUnusedIVars.cpp
index 21dc658dfa1a..0063c40482a0 100644
--- a/lib/Analysis/CheckObjCUnusedIVars.cpp
+++ b/lib/Analysis/CheckObjCUnusedIVars.cpp
@@ -59,9 +59,6 @@ void clang::CheckObjCUnusedIvar(ObjCImplementationDecl* D, BugReporter& BR) {
ObjCInterfaceDecl* ID = D->getClassInterface();
IvarUsageMap M;
-
- ASTContext &Ctx = BR.getContext();
-
// Iterate over the ivars.
for (ObjCInterfaceDecl::ivar_iterator I=ID->ivar_begin(), E=ID->ivar_end();
I!=E; ++I) {
@@ -73,7 +70,7 @@ void clang::CheckObjCUnusedIvar(ObjCImplementationDecl* D, BugReporter& BR) {
continue;
// Skip IB Outlets.
- if (ID->getAttr<IBOutletAttr>(Ctx))
+ if (ID->getAttr<IBOutletAttr>())
continue;
M[ID] = Unused;
@@ -83,14 +80,14 @@ void clang::CheckObjCUnusedIvar(ObjCImplementationDecl* D, BugReporter& BR) {
return;
// Now scan the methods for accesses.
- for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(Ctx),
- E = D->instmeth_end(Ctx); I!=E; ++I)
- Scan(M, (*I)->getBody(Ctx));
+ for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(),
+ E = D->instmeth_end(); I!=E; ++I)
+ Scan(M, (*I)->getBody());
// Scan for @synthesized property methods that act as setters/getters
// to an ivar.
- for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(Ctx),
- E = D->propimpl_end(Ctx); I!=E; ++I)
+ for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(),
+ E = D->propimpl_end(); I!=E; ++I)
Scan(M, *I);
// Find ivars that are unused.
diff --git a/lib/Analysis/Environment.cpp b/lib/Analysis/Environment.cpp
index 2b751df830c2..3f8f14dcb0b4 100644
--- a/lib/Analysis/Environment.cpp
+++ b/lib/Analysis/Environment.cpp
@@ -143,8 +143,19 @@ EnvironmentManager::RemoveDeadBindings(Environment Env, Stmt* Loc,
SVal X = I.getData();
// If the block expr's value is a memory region, then mark that region.
- if (isa<loc::MemRegionVal>(X))
- DRoots.push_back(cast<loc::MemRegionVal>(X).getRegion());
+ if (isa<loc::MemRegionVal>(X)) {
+ const MemRegion* R = cast<loc::MemRegionVal>(X).getRegion();
+ DRoots.push_back(R);
+ // Mark the super region of the RX as live.
+ // e.g.: int x; char *y = (char*) &x; if (*y) ...
+ // 'y' => element region. 'x' is its super region.
+ // We only add one level super region for now.
+
+ // FIXME: maybe multiple level of super regions should be added.
+ if (const SubRegion *SR = dyn_cast<SubRegion>(R)) {
+ DRoots.push_back(SR->getSuperRegion());
+ }
+ }
// Mark all symbols in the block expr's value live.
MarkLiveCallback cb(SymReaper);
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index 8b4f5c8f11c1..d9117f5930e6 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -1437,8 +1437,8 @@ void GRExprEngine::VisitCallRec(CallExpr* CE, NodeTy* Pred,
SaveAndRestore<bool> OldSink(Builder->BuildSinks);
const FunctionDecl* FD = L.getAsFunctionDecl();
if (FD) {
- if (FD->getAttr<NoReturnAttr>(getContext()) ||
- FD->getAttr<AnalyzerNoReturnAttr>(getContext()))
+ if (FD->getAttr<NoReturnAttr>() ||
+ FD->getAttr<AnalyzerNoReturnAttr>())
Builder->BuildSinks = true;
else {
// HACK: Some functions are not marked noreturn, and don't return.
@@ -3154,7 +3154,8 @@ struct VISIBILITY_HIDDEN DOTGraphTraits<GRExprEngine::NodeTy*> :
SourceLocation SLoc = S->getLocStart();
Out << S->getStmtClassName() << ' ' << (void*) S << ' ';
- S->printPretty(Out);
+ LangOptions LO; // FIXME.
+ S->printPretty(Out, 0, PrintingPolicy(LO));
if (SLoc.isFileID()) {
Out << "\\lline="
@@ -3208,7 +3209,8 @@ struct VISIBILITY_HIDDEN DOTGraphTraits<GRExprEngine::NodeTy*> :
SourceLocation SLoc = T->getLocStart();
Out << "\\|Terminator: ";
- E.getSrc()->printTerminator(Out);
+ LangOptions LO; // FIXME.
+ E.getSrc()->printTerminator(Out, LO);
if (SLoc.isFileID()) {
Out << "\\lline="
@@ -3223,11 +3225,12 @@ struct VISIBILITY_HIDDEN DOTGraphTraits<GRExprEngine::NodeTy*> :
if (Label) {
if (CaseStmt* C = dyn_cast<CaseStmt>(Label)) {
Out << "\\lcase ";
- C->getLHS()->printPretty(Out);
+ LangOptions LO; // FIXME.
+ C->getLHS()->printPretty(Out, 0, PrintingPolicy(LO));
if (Stmt* RHS = C->getRHS()) {
Out << " .. ";
- RHS->printPretty(Out);
+ RHS->printPretty(Out, 0, PrintingPolicy(LO));
}
Out << ":";
diff --git a/lib/Analysis/GRExprEngineInternalChecks.cpp b/lib/Analysis/GRExprEngineInternalChecks.cpp
index 76d26dd9f02a..a2ce79a2f390 100644
--- a/lib/Analysis/GRExprEngineInternalChecks.cpp
+++ b/lib/Analysis/GRExprEngineInternalChecks.cpp
@@ -566,7 +566,7 @@ public:
if (!FD)
return false;
- const NonNullAttr* Att = FD->getAttr<NonNullAttr>(BR.getContext());
+ const NonNullAttr* Att = FD->getAttr<NonNullAttr>();
if (!Att)
return false;
diff --git a/lib/Analysis/GRState.cpp b/lib/Analysis/GRState.cpp
index 493edc37bacb..54c0afbff33e 100644
--- a/lib/Analysis/GRState.cpp
+++ b/lib/Analysis/GRState.cpp
@@ -166,7 +166,8 @@ void GRState::print(llvm::raw_ostream& Out, const char* nl,
else { Out << nl; }
Out << " (" << (void*) I.getKey() << ") ";
- I.getKey()->printPretty(Out);
+ LangOptions LO; // FIXME.
+ I.getKey()->printPretty(Out, 0, PrintingPolicy(LO));
Out << " : ";
I.getData().print(Out);
}
@@ -183,7 +184,8 @@ void GRState::print(llvm::raw_ostream& Out, const char* nl,
else { Out << nl; }
Out << " (" << (void*) I.getKey() << ") ";
- I.getKey()->printPretty(Out);
+ LangOptions LO; // FIXME.
+ I.getKey()->printPretty(Out, 0, PrintingPolicy(LO));
Out << " : ";
I.getData().print(Out);
}
diff --git a/lib/Analysis/LiveVariables.cpp b/lib/Analysis/LiveVariables.cpp
index b0eb37b06524..aead7f43ad8f 100644
--- a/lib/Analysis/LiveVariables.cpp
+++ b/lib/Analysis/LiveVariables.cpp
@@ -135,9 +135,10 @@ void TransferFuncs::Visit(Stmt *S) {
StmtVisitor<TransferFuncs,void>::Visit(S);
}
- else
+ else {
// For block-level expressions, mark that they are live.
LiveState(S,AD) = Alive;
+ }
}
void TransferFuncs::VisitTerminator(CFGBlock* B) {
diff --git a/lib/Analysis/MemRegion.cpp b/lib/Analysis/MemRegion.cpp
index c8e027579a30..45305403585a 100644
--- a/lib/Analysis/MemRegion.cpp
+++ b/lib/Analysis/MemRegion.cpp
@@ -143,6 +143,10 @@ void CodeTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
// Region pretty-printing.
//===----------------------------------------------------------------------===//
+void MemRegion::printStdErr() const {
+ print(llvm::errs());
+}
+
std::string MemRegion::getString() const {
std::string s;
llvm::raw_string_ostream os(s);
@@ -184,7 +188,8 @@ void FieldRegion::print(llvm::raw_ostream& os) const {
}
void StringRegion::print(llvm::raw_ostream& os) const {
- Str->printPretty(os);
+ LangOptions LO; // FIXME.
+ Str->printPretty(os, 0, PrintingPolicy(LO));
}
void SymbolicRegion::print(llvm::raw_ostream& os) const {
@@ -218,6 +223,10 @@ MemSpaceRegion* MemRegionManager::getStackRegion() {
return LazyAllocate(stack);
}
+MemSpaceRegion* MemRegionManager::getStackArgumentsRegion() {
+ return LazyAllocate(stackArguments);
+}
+
MemSpaceRegion* MemRegionManager::getGlobalsRegion() {
return LazyAllocate(globals);
}
@@ -327,8 +336,10 @@ const MemSpaceRegion *MemRegion::getMemorySpace() const {
}
bool MemRegion::hasStackStorage() const {
- if (const MemSpaceRegion *MS = getMemorySpace())
- return MS == getMemRegionManager()->getStackRegion();
+ if (const MemSpaceRegion *MS = getMemorySpace()) {
+ MemRegionManager *Mgr = getMemRegionManager();
+ return MS == Mgr->getStackRegion() || MS == Mgr->getStackArgumentsRegion();
+ }
return false;
}
@@ -343,10 +354,35 @@ bool MemRegion::hasHeapStorage() const {
bool MemRegion::hasHeapOrStackStorage() const {
if (const MemSpaceRegion *MS = getMemorySpace()) {
MemRegionManager *Mgr = getMemRegionManager();
- return MS == Mgr->getHeapRegion() || MS == Mgr->getStackRegion();
+ return MS == Mgr->getHeapRegion()
+ || MS == Mgr->getStackRegion()
+ || MS == Mgr->getStackArgumentsRegion();
}
return false;
-}
+}
+
+bool MemRegion::hasGlobalsStorage() const {
+ if (const MemSpaceRegion *MS = getMemorySpace())
+ return MS == getMemRegionManager()->getGlobalsRegion();
+
+ return false;
+}
+
+bool MemRegion::hasParametersStorage() const {
+ if (const MemSpaceRegion *MS = getMemorySpace())
+ return MS == getMemRegionManager()->getStackArgumentsRegion();
+
+ return false;
+}
+
+bool MemRegion::hasGlobalsOrParametersStorage() const {
+ if (const MemSpaceRegion *MS = getMemorySpace()) {
+ MemRegionManager *Mgr = getMemRegionManager();
+ return MS == Mgr->getGlobalsRegion()
+ || MS == Mgr->getStackArgumentsRegion();
+ }
+ return false;
+}
//===----------------------------------------------------------------------===//
// View handling.
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp
index d45048de1a42..23e8b738b601 100644
--- a/lib/Analysis/RegionStore.cpp
+++ b/lib/Analysis/RegionStore.cpp
@@ -347,9 +347,6 @@ public:
// FIXME: Remove.
ASTContext& getContext() { return StateMgr.getContext(); }
-
- // FIXME: Use ValueManager?
- SymbolManager& getSymbolManager() { return StateMgr.getSymbolManager(); }
};
} // end anonymous namespace
@@ -822,12 +819,6 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {
const TypedRegion *R = cast<TypedRegion>(MR);
assert(R && "bad region");
- if (const FieldRegion* FR = dyn_cast<FieldRegion>(R))
- return RetrieveField(state, FR);
-
- if (const ElementRegion* ER = dyn_cast<ElementRegion>(R))
- return RetrieveElement(state, ER);
-
// FIXME: We should eventually handle funny addressing. e.g.:
//
// int x = ...;
@@ -848,6 +839,12 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {
// FIXME: handle Vector types.
if (RTy->isVectorType())
return UnknownVal();
+
+ if (const FieldRegion* FR = dyn_cast<FieldRegion>(R))
+ return RetrieveField(state, FR);
+
+ if (const ElementRegion* ER = dyn_cast<ElementRegion>(R))
+ return RetrieveElement(state, ER);
RegionBindingsTy B = GetRegionBindings(state->getStore());
RegionBindingsTy::data_type* V = B.lookup(R);
@@ -882,14 +879,8 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {
if (VD == SelfDecl)
return loc::MemRegionVal(getSelfRegion(0));
- if (isa<ParmVarDecl>(VD) || isa<ImplicitParamDecl>(VD) ||
- VD->hasGlobalStorage()) {
- QualType VTy = VD->getType();
- if (Loc::IsLocType(VTy) || VTy->isIntegerType())
- return ValMgr.getRegionValueSymbolVal(VR);
- else
- return UnknownVal();
- }
+ if (VR->hasGlobalsOrParametersStorage())
+ return ValMgr.getRegionValueSymbolValOrUnknown(VR, VD->getType());
}
if (R->hasHeapOrStackStorage()) {
@@ -907,23 +898,21 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {
RTy = T->getAsPointerType()->getPointeeType();
}
- // All other integer values are symbolic.
- if (Loc::IsLocType(RTy) || RTy->isIntegerType())
- return ValMgr.getRegionValueSymbolVal(R, RTy);
- else
- return UnknownVal();
+ // All other values are symbolic.
+ return ValMgr.getRegionValueSymbolValOrUnknown(R, RTy);
}
SVal RegionStoreManager::RetrieveElement(const GRState* state,
const ElementRegion* R) {
// Check if the region has a binding.
RegionBindingsTy B = GetRegionBindings(state->getStore());
- const SVal* V = B.lookup(R);
- if (V)
+ if (const SVal* V = B.lookup(R))
return *V;
+ const MemRegion* superR = R->getSuperRegion();
+
// Check if the region is an element region of a string literal.
- if (const StringRegion *StrR=dyn_cast<StringRegion>(R->getSuperRegion())) {
+ if (const StringRegion *StrR=dyn_cast<StringRegion>(superR)) {
const StringLiteral *Str = StrR->getStringLiteral();
SVal Idx = R->getIndex();
if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&Idx)) {
@@ -937,18 +926,38 @@ SVal RegionStoreManager::RetrieveElement(const GRState* state,
}
}
- const MemRegion* SuperR = R->getSuperRegion();
- const SVal* D = state->get<RegionDefaultValue>(SuperR);
-
- if (D) {
+ // Check if the super region has a default value.
+ if (const SVal *D = state->get<RegionDefaultValue>(superR)) {
if (D->hasConjuredSymbol())
return ValMgr.getRegionValueSymbolVal(R);
else
return *D;
}
- if (R->hasHeapOrStackStorage())
+ // Check if the super region has a binding.
+ if (B.lookup(superR)) {
+ // We do not extract the bit value from super region for now.
+ return UnknownVal();
+ }
+
+ if (R->hasHeapStorage()) {
+ // FIXME: If the region has heap storage and we know nothing special
+ // about its bindings, should we instead return UnknownVal? Seems like
+ // we should only return UndefinedVal in the cases where we know the value
+ // will be undefined.
return UndefinedVal();
+ }
+
+ if (R->hasStackStorage() && !R->hasParametersStorage()) {
+ // Currently we don't reason specially about Clang-style vectors. Check
+ // if superR is a vector and if so return Unknown.
+ if (const TypedRegion *typedSuperR = dyn_cast<TypedRegion>(superR)) {
+ if (typedSuperR->getValueType(getContext())->isVectorType())
+ return UnknownVal();
+ }
+
+ return UndefinedVal();
+ }
QualType Ty = R->getValueType(getContext());
@@ -957,10 +966,7 @@ SVal RegionStoreManager::RetrieveElement(const GRState* state,
if (const QualType *p = state->get<RegionCasts>(R))
Ty = (*p)->getAsPointerType()->getPointeeType();
- if (Loc::IsLocType(Ty) || Ty->isIntegerType())
- return ValMgr.getRegionValueSymbolVal(R, Ty);
- else
- return UnknownVal();
+ return ValMgr.getRegionValueSymbolValOrUnknown(R, Ty);
}
SVal RegionStoreManager::RetrieveField(const GRState* state,
@@ -969,13 +975,11 @@ SVal RegionStoreManager::RetrieveField(const GRState* state,
// Check if the region has a binding.
RegionBindingsTy B = GetRegionBindings(state->getStore());
- const SVal* V = B.lookup(R);
- if (V)
+ if (const SVal* V = B.lookup(R))
return *V;
- const MemRegion* SuperR = R->getSuperRegion();
- const SVal* D = state->get<RegionDefaultValue>(SuperR);
- if (D) {
+ const MemRegion* superR = R->getSuperRegion();
+ if (const SVal* D = state->get<RegionDefaultValue>(superR)) {
if (D->hasConjuredSymbol())
return ValMgr.getRegionValueSymbolVal(R);
@@ -988,7 +992,11 @@ SVal RegionStoreManager::RetrieveField(const GRState* state,
assert(0 && "Unknown default value");
}
- if (R->hasHeapOrStackStorage())
+ // FIXME: Is this correct? Should it be UnknownVal?
+ if (R->hasHeapStorage())
+ return UndefinedVal();
+
+ if (R->hasStackStorage() && !R->hasParametersStorage())
return UndefinedVal();
// If the region is already cast to another type, use that type to create the
@@ -998,11 +1006,8 @@ SVal RegionStoreManager::RetrieveField(const GRState* state,
Ty = tmp->getAsPointerType()->getPointeeType();
}
- // All other integer values are symbolic.
- if (Loc::IsLocType(Ty) || Ty->isIntegerType())
- return ValMgr.getRegionValueSymbolVal(R, Ty);
- else
- return UnknownVal();
+ // All other values are symbolic.
+ return ValMgr.getRegionValueSymbolValOrUnknown(R, Ty);
}
SVal RegionStoreManager::RetrieveStruct(const GRState *state,
@@ -1018,8 +1023,7 @@ SVal RegionStoreManager::RetrieveStruct(const GRState *state,
// FIXME: We shouldn't use a std::vector. If RecordDecl doesn't have a
// reverse iterator, we should implement one.
- std::vector<FieldDecl *> Fields(RD->field_begin(getContext()),
- RD->field_end(getContext()));
+ std::vector<FieldDecl *> Fields(RD->field_begin(), RD->field_end());
for (std::vector<FieldDecl *>::reverse_iterator Field = Fields.rbegin(),
FieldEnd = Fields.rend();
@@ -1074,6 +1078,9 @@ Store RegionStoreManager::Remove(Store store, Loc L) {
}
const GRState *RegionStoreManager::Bind(const GRState *state, Loc L, SVal V) {
+ if (isa<loc::ConcreteInt>(L))
+ return state;
+
// If we get here, the location should be a region.
const MemRegion* R = cast<loc::MemRegionVal>(L).getRegion();
@@ -1204,8 +1211,7 @@ RegionStoreManager::BindStruct(const GRState *state, const TypedRegion* R,
RecordDecl::field_iterator FI, FE;
- for (FI = RD->field_begin(getContext()), FE = RD->field_end(getContext());
- FI != FE; ++FI, ++VI) {
+ for (FI = RD->field_begin(), FE = RD->field_end(); FI != FE; ++FI, ++VI) {
if (VI == VE)
break;
@@ -1357,8 +1363,9 @@ Store RegionStoreManager::RemoveDeadBindings(const GRState *state, Stmt* Loc,
IntermediateRoots.pop_back();
if (const VarRegion* VR = dyn_cast<VarRegion>(R)) {
- if (SymReaper.isLive(Loc, VR->getDecl()))
+ if (SymReaper.isLive(Loc, VR->getDecl())) {
RegionRoots.push_back(VR); // This is a live "root".
+ }
}
else if (const SymbolicRegion* SR = dyn_cast<SymbolicRegion>(R)) {
if (SymReaper.isLive(SR->getSymbol()))
@@ -1366,19 +1373,19 @@ Store RegionStoreManager::RemoveDeadBindings(const GRState *state, Stmt* Loc,
}
else {
// Get the super region for R.
- const MemRegion* SuperR = cast<SubRegion>(R)->getSuperRegion();
+ const MemRegion* superR = cast<SubRegion>(R)->getSuperRegion();
// Get the current set of subregions for SuperR.
- const SubRegionsTy* SRptr = SubRegMap.lookup(SuperR);
+ const SubRegionsTy* SRptr = SubRegMap.lookup(superR);
SubRegionsTy SRs = SRptr ? *SRptr : SubRegF.GetEmptySet();
// Add R to the subregions of SuperR.
- SubRegMap = SubRegMapF.Add(SubRegMap, SuperR, SubRegF.Add(SRs, R));
+ SubRegMap = SubRegMapF.Add(SubRegMap, superR, SubRegF.Add(SRs, R));
// Super region may be VarRegion or subregion of another VarRegion. Add it
// to the work list.
- if (isa<SubRegion>(SuperR))
- IntermediateRoots.push_back(SuperR);
+ if (isa<SubRegion>(superR))
+ IntermediateRoots.push_back(superR);
}
}
@@ -1409,9 +1416,19 @@ Store RegionStoreManager::RemoveDeadBindings(const GRState *state, Stmt* Loc,
SVal X = *Xptr;
UpdateLiveSymbols(X, SymReaper); // Update the set of live symbols.
- // If X is a region, then add it the RegionRoots.
- if (loc::MemRegionVal* RegionX = dyn_cast<loc::MemRegionVal>(&X))
- RegionRoots.push_back(RegionX->getRegion());
+ // If X is a region, then add it to the RegionRoots.
+ if (const MemRegion *RX = X.getAsRegion()) {
+ RegionRoots.push_back(RX);
+
+ // Mark the super region of the RX as live.
+ // e.g.: int x; char *y = (char*) &x; if (*y) ...
+ // 'y' => element region. 'x' is its super region.
+ // We only add one level super region for now.
+ // FIXME: maybe multiple level of super regions should be added.
+ if (const SubRegion *SR = dyn_cast<SubRegion>(RX)) {
+ RegionRoots.push_back(SR->getSuperRegion());
+ }
+ }
}
// Get the subregions of R. These are RegionRoots as well since they
@@ -1422,6 +1439,7 @@ Store RegionStoreManager::RemoveDeadBindings(const GRState *state, Stmt* Loc,
for (SubRegionsTy::iterator I=SR.begin(), E=SR.end(); I!=E; ++I)
RegionRoots.push_back(*I);
+
}
// We have now scanned the store, marking reachable regions and symbols
@@ -1429,7 +1447,6 @@ Store RegionStoreManager::RemoveDeadBindings(const GRState *state, Stmt* Loc,
// as well as update DSymbols with the set symbols that are now dead.
for (RegionBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {
const MemRegion* R = I.getKey();
-
// If this region live? Is so, none of its symbols are dead.
if (Marked.count(R))
continue;
diff --git a/lib/Analysis/SVals.cpp b/lib/Analysis/SVals.cpp
index 7d1850d73095..d711ce0a225e 100644
--- a/lib/Analysis/SVals.cpp
+++ b/lib/Analysis/SVals.cpp
@@ -114,6 +114,13 @@ const SymExpr *SVal::getAsSymbolicExpression() const {
return getAsSymbol();
}
+const MemRegion *SVal::getAsRegion() const {
+ if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this))
+ return X->getRegion();
+
+ return 0;
+}
+
bool SVal::symbol_iterator::operator==(const symbol_iterator &X) const {
return itr == X.itr;
}
diff --git a/lib/Analysis/Store.cpp b/lib/Analysis/Store.cpp
index 5aa756e14be3..cb099862f055 100644
--- a/lib/Analysis/Store.cpp
+++ b/lib/Analysis/Store.cpp
@@ -88,10 +88,10 @@ StoreManager::CastRegion(const GRState* state, const MemRegion* R,
// If the super region is an element region, strip it away.
// FIXME: Is this the right thing to do in all cases?
- const TypedRegion *Base = isa<ElementRegion>(TR) ?
- cast<TypedRegion>(TR->getSuperRegion()) : TR;
+ const MemRegion *Base = isa<ElementRegion>(TR) ? TR->getSuperRegion()
+ : TR;
ElementRegion* ER = MRMgr.getElementRegion(Pointee, Idx, Base,
- StateMgr.getContext());
+ StateMgr.getContext());
return CastResult(state, ER);
}
}
diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp
index d13ffa38213e..3810c49f71f3 100644
--- a/lib/Basic/IdentifierTable.cpp
+++ b/lib/Basic/IdentifierTable.cpp
@@ -89,7 +89,7 @@ static void AddKeyword(const char *Keyword, unsigned KWLen,
else if (LangOpts.C99 && (Flags & KEYC99)) AddResult = 2;
else if (LangOpts.GNUMode && (Flags & KEYGNU)) AddResult = 1;
else if (LangOpts.Microsoft && (Flags & KEYMS)) AddResult = 1;
- else if (LangOpts.OpenCL && (Flags & BOOLSUPPORT)) AddResult = 2;
+ else if (LangOpts.Bool && (Flags & BOOLSUPPORT)) AddResult = 2;
// Don't add this keyword if disabled in this language.
if (AddResult == 0) return;
diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp
index a513cb16886e..ba7f190408b2 100644
--- a/lib/Basic/TargetInfo.cpp
+++ b/lib/Basic/TargetInfo.cpp
@@ -41,6 +41,7 @@ TargetInfo::TargetInfo(const std::string &T) : Triple(T) {
UIntMaxType = UnsignedLongLong;
IntPtrType = SignedLong;
WCharType = SignedInt;
+ Int64Type = SignedLongLong;
FloatFormat = &llvm::APFloat::IEEEsingle;
DoubleFormat = &llvm::APFloat::IEEEdouble;
LongDoubleFormat = &llvm::APFloat::IEEEdouble;
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 9910e28fcda9..3f7d9a31c61e 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -61,55 +61,24 @@ static void DefineStd(std::vector<char> &Buf, const char *MacroName,
//===----------------------------------------------------------------------===//
// Defines specific to certain operating systems.
//===----------------------------------------------------------------------===//
-
-static void getSolarisDefines(const LangOptions &Opts, std::vector<char> &Defs) {
- DefineStd(Defs, "sun", Opts);
- DefineStd(Defs, "unix", Opts);
- Define(Defs, "__ELF__");
- Define(Defs, "__svr4__");
- Define(Defs, "__SVR4");
-}
-
-static void getFreeBSDDefines(const LangOptions &Opts, bool is64Bit,
- const char *Triple, std::vector<char> &Defs) {
- // FreeBSD defines; list based off of gcc output
-
- const char *FreeBSD = strstr(Triple, "-freebsd");
- FreeBSD += strlen("-freebsd");
- char release[] = "X";
- release[0] = FreeBSD[0];
- char version[] = "X00001";
- version[0] = FreeBSD[0];
-
- Define(Defs, "__FreeBSD__", release);
- Define(Defs, "__FreeBSD_cc_version", version);
- Define(Defs, "__KPRINTF_ATTRIBUTE__");
- DefineStd(Defs, "unix", Opts);
- Define(Defs, "__ELF__", "1");
- if (is64Bit) {
- Define(Defs, "__LP64__");
+namespace {
+template<typename TgtInfo>
+class OSTargetInfo : public TgtInfo {
+protected:
+ virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
+ std::vector<char> &Defines) const=0;
+public:
+ OSTargetInfo(const std::string& triple) : TgtInfo(triple) {}
+ virtual void getTargetDefines(const LangOptions &Opts,
+ std::vector<char> &Defines) const {
+ TgtInfo::getTargetDefines(Opts, Defines);
+ getOSDefines(Opts, TgtInfo::getTargetTriple(), Defines);
}
-}
-
-static void getDragonFlyDefines(const LangOptions &Opts,
- std::vector<char> &Defs) {
- // DragonFly defines; list based off of gcc output
- Define(Defs, "__DragonFly__");
- Define(Defs, "__DragonFly_cc_version", "100001");
- Define(Defs, "__ELF__");
- Define(Defs, "__KPRINTF_ATTRIBUTE__");
- Define(Defs, "__tune_i386__");
- DefineStd(Defs, "unix", Opts);
-}
-static void getLinuxDefines(const LangOptions &Opts, std::vector<char> &Defs) {
- // Linux defines; list based off of gcc output
- DefineStd(Defs, "unix", Opts);
- DefineStd(Defs, "linux", Opts);
- Define(Defs, "__gnu_linux__");
- Define(Defs, "__ELF__", "1");
+};
}
+namespace {
/// getDarwinNumber - Parse the 'darwin number' out of the specific targe
/// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
/// not defined, return 0's. Return true if we have -darwin in the string or
@@ -235,15 +204,160 @@ static void GetDarwinLanguageOptions(LangOptions &Opts,
if (!getDarwinNumber(Triple, Maj, Min, Rev))
return;
- // Blocks default to on for 10.6 (darwin10) and beyond.
- // As does nonfragile-abi for 64bit mode
- if (Maj > 9)
+ // Blocks and stack protectors default to on for 10.6 (darwin10) and beyond.
+ if (Maj > 9) {
Opts.Blocks = 1;
+ Opts.setStackProtectorMode(LangOptions::SSPOn);
+ }
+ // Non-fragile ABI (in 64-bit mode) default to on for 10.5 (darwin9) and
+ // beyond.
if (Maj >= 9 && Opts.ObjC1 && !strncmp(Triple, "x86_64", 6))
Opts.ObjCNonFragileABI = 1;
}
+template<typename Target>
+class DarwinTargetInfo : public OSTargetInfo<Target> {
+protected:
+ virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
+ std::vector<char> &Defines) const {
+ getDarwinDefines(Defines, Opts);
+ getDarwinOSXDefines(Defines, Triple);
+ }
+
+ /// getDefaultLangOptions - Allow the target to specify default settings for
+ /// various language options. These may be overridden by command line
+ /// options.
+ virtual void getDefaultLangOptions(LangOptions &Opts) {
+ TargetInfo::getDefaultLangOptions(Opts);
+ GetDarwinLanguageOptions(Opts, TargetInfo::getTargetTriple());
+ }
+public:
+ DarwinTargetInfo(const std::string& triple) :
+ OSTargetInfo<Target>(triple) {
+ this->TLSSupported = false;
+ }
+
+ virtual const char *getCFStringSymbolPrefix() const {
+ return "\01L_unnamed_cfstring_";
+ }
+
+ virtual const char *getStringSymbolPrefix(bool IsConstant) const {
+ return IsConstant ? "\01LC" : "\01lC";
+ }
+
+ virtual const char *getUnicodeStringSymbolPrefix() const {
+ return "__utf16_string_";
+ }
+
+ virtual const char *getUnicodeStringSection() const {
+ return "__TEXT,__ustring";
+ }
+};
+
+// DragonFlyBSD Target
+template<typename Target>
+class DragonFlyBSDTargetInfo : public OSTargetInfo<Target> {
+protected:
+ virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
+ std::vector<char> &Defs) const {
+ // DragonFly defines; list based off of gcc output
+ Define(Defs, "__DragonFly__");
+ Define(Defs, "__DragonFly_cc_version", "100001");
+ Define(Defs, "__ELF__");
+ Define(Defs, "__KPRINTF_ATTRIBUTE__");
+ Define(Defs, "__tune_i386__");
+ DefineStd(Defs, "unix", Opts);
+ }
+public:
+ DragonFlyBSDTargetInfo(const std::string &triple)
+ : OSTargetInfo<Target>(triple) {}
+};
+
+// FreeBSD Target
+template<typename Target>
+class FreeBSDTargetInfo : public OSTargetInfo<Target> {
+protected:
+ virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
+ std::vector<char> &Defs) const {
+ // FreeBSD defines; list based off of gcc output
+
+ const char *FreeBSD = strstr(Triple, "-freebsd");
+ FreeBSD += strlen("-freebsd");
+ char release[] = "X";
+ release[0] = FreeBSD[0];
+ char version[] = "X00001";
+ version[0] = FreeBSD[0];
+
+ Define(Defs, "__FreeBSD__", release);
+ Define(Defs, "__FreeBSD_cc_version", version);
+ Define(Defs, "__KPRINTF_ATTRIBUTE__");
+ DefineStd(Defs, "unix", Opts);
+ Define(Defs, "__ELF__", "1");
+ }
+public:
+ FreeBSDTargetInfo(const std::string &triple)
+ : OSTargetInfo<Target>(triple) {}
+};
+
+// Linux target
+template<typename Target>
+class LinuxTargetInfo : public OSTargetInfo<Target> {
+protected:
+ virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
+ std::vector<char> &Defs) const {
+ // Linux defines; list based off of gcc output
+ DefineStd(Defs, "unix", Opts);
+ DefineStd(Defs, "linux", Opts);
+ Define(Defs, "__gnu_linux__");
+ Define(Defs, "__ELF__", "1");
+ }
+public:
+ LinuxTargetInfo(const std::string& triple)
+ : OSTargetInfo<Target>(triple) {
+ this->UserLabelPrefix = "";
+ }
+};
+
+// OpenBSD Target
+template<typename Target>
+class OpenBSDTargetInfo : public OSTargetInfo<Target> {
+protected:
+ virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
+ std::vector<char> &Defs) const {
+ // OpenBSD defines; list based off of gcc output
+
+ Define(Defs, "__OpenBSD__", "1");
+ DefineStd(Defs, "unix", Opts);
+ Define(Defs, "__ELF__", "1");
+ }
+public:
+ OpenBSDTargetInfo(const std::string &triple)
+ : OSTargetInfo<Target>(triple) {}
+};
+
+// Solaris target
+template<typename Target>
+class SolarisTargetInfo : public OSTargetInfo<Target> {
+protected:
+ virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
+ std::vector<char> &Defs) const {
+ DefineStd(Defs, "sun", Opts);
+ DefineStd(Defs, "unix", Opts);
+ Define(Defs, "__ELF__");
+ Define(Defs, "__svr4__");
+ Define(Defs, "__SVR4");
+ }
+public:
+ SolarisTargetInfo(const std::string& triple)
+ : OSTargetInfo<Target>(triple) {
+ this->UserLabelPrefix = "";
+ this->WCharType = this->SignedLong;
+ // FIXME: WIntType should be SignedLong
+ }
+};
+} // end anonymous namespace.
+
/// GetWindowsLanguageOptions - Set the default language options for Windows.
static void GetWindowsLanguageOptions(LangOptions &Opts,
const char *Triple) {
@@ -435,55 +549,15 @@ class PPC64TargetInfo : public PPCTargetInfo {
public:
PPC64TargetInfo(const std::string& triple) : PPCTargetInfo(triple) {
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
+ IntMaxType = SignedLong;
+ UIntMaxType = UnsignedLong;
+ Int64Type = SignedLong;
DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
"i64:64:64-f32:32:32-f64:64:64-v128:128:128";
}
};
} // end anonymous namespace.
-
-namespace {
-class DarwinPPCTargetInfo : public PPC32TargetInfo {
-public:
- DarwinPPCTargetInfo(const std::string& triple) : PPC32TargetInfo(triple) {}
- virtual void getTargetDefines(const LangOptions &Opts,
- std::vector<char> &Defines) const {
- PPC32TargetInfo::getTargetDefines(Opts, Defines);
- getDarwinDefines(Defines, Opts);
- getDarwinOSXDefines(Defines, getTargetTriple());
- }
-
- /// getDefaultLangOptions - Allow the target to specify default settings for
- /// various language options. These may be overridden by command line
- /// options.
- virtual void getDefaultLangOptions(LangOptions &Opts) {
- PPC32TargetInfo::getDefaultLangOptions(Opts);
- GetDarwinLanguageOptions(Opts, getTargetTriple());
- }
-};
-} // end anonymous namespace.
-
-namespace {
-class DarwinPPC64TargetInfo : public PPC64TargetInfo {
-public:
- DarwinPPC64TargetInfo(const std::string& triple) : PPC64TargetInfo(triple) {}
- virtual void getTargetDefines(const LangOptions &Opts,
- std::vector<char> &Defines) const {
- PPC64TargetInfo::getTargetDefines(Opts, Defines);
- getDarwinDefines(Defines, Opts);
- getDarwinOSXDefines(Defines, getTargetTriple());
- }
-
- /// getDefaultLangOptions - Allow the target to specify default settings for
- /// various language options. These may be overridden by command line
- /// options.
- virtual void getDefaultLangOptions(LangOptions &Opts) {
- PPC64TargetInfo::getDefaultLangOptions(Opts);
- GetDarwinLanguageOptions(Opts, getTargetTriple());
- }
-};
-} // end anonymous namespace.
-
namespace {
// Namespace for x86 abstract base class
const Builtin::Info BuiltinInfo[] = {
@@ -815,10 +889,10 @@ public:
} // end anonymous namespace
namespace {
-// x86-32 Darwin (OS X) target
-class DarwinI386TargetInfo : public X86_32TargetInfo {
+class DarwinI386TargetInfo : public DarwinTargetInfo<X86_32TargetInfo> {
public:
- DarwinI386TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
+ DarwinI386TargetInfo(const std::string& triple) :
+ DarwinTargetInfo<X86_32TargetInfo>(triple) {
LongDoubleWidth = 128;
LongDoubleAlign = 128;
SizeType = UnsignedLong;
@@ -826,104 +900,12 @@ public:
DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
"i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
"a0:0:64-f80:128:128";
- TLSSupported = false;
- }
-
- virtual const char *getStringSymbolPrefix(bool IsConstant) const {
- return IsConstant ? "\01LC" : "\01lC";
- }
-
- virtual const char *getUnicodeStringSymbolPrefix() const {
- return "__utf16_string_";
- }
-
- virtual const char *getUnicodeStringSection() const {
- return "__TEXT,__ustring";
- }
-
- virtual const char *getCFStringSymbolPrefix() const {
- return "\01LC";
- }
-
- virtual void getTargetDefines(const LangOptions &Opts,
- std::vector<char> &Defines) const {
- X86_32TargetInfo::getTargetDefines(Opts, Defines);
- getDarwinDefines(Defines, Opts);
- getDarwinOSXDefines(Defines, getTargetTriple());
- }
-
- /// getDefaultLangOptions - Allow the target to specify default settings for
- /// various language options. These may be overridden by command line
- /// options.
- virtual void getDefaultLangOptions(LangOptions &Opts) {
- X86_32TargetInfo::getDefaultLangOptions(Opts);
- GetDarwinLanguageOptions(Opts, getTargetTriple());
}
-};
-} // end anonymous namespace
-namespace {
-// x86-32 FreeBSD target
-class FreeBSDX86_32TargetInfo : public X86_32TargetInfo {
-public:
- FreeBSDX86_32TargetInfo(const std::string& triple) :
- X86_32TargetInfo(triple) { }
- virtual void getTargetDefines(const LangOptions &Opts,
- std::vector<char> &Defines) const {
- X86_32TargetInfo::getTargetDefines(Opts, Defines);
- getFreeBSDDefines(Opts, 0, getTargetTriple(), Defines);
- }
};
} // end anonymous namespace
namespace {
-// x86-32 DragonFly target
-class DragonFlyX86_32TargetInfo : public X86_32TargetInfo {
-public:
- DragonFlyX86_32TargetInfo(const std::string& triple) :
- X86_32TargetInfo(triple) { }
- virtual void getTargetDefines(const LangOptions &Opts,
- std::vector<char> &Defines) const {
- X86_32TargetInfo::getTargetDefines(Opts, Defines);
- getDragonFlyDefines(Opts, Defines);
- }
-};
-} // end anonymous namespace
-
-namespace {
-// x86-32 Linux target
-class LinuxX86_32TargetInfo : public X86_32TargetInfo {
-public:
- LinuxX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
- UserLabelPrefix = "";
- }
- virtual void getTargetDefines(const LangOptions &Opts,
- std::vector<char> &Defines) const {
- X86_32TargetInfo::getTargetDefines(Opts, Defines);
- getLinuxDefines(Opts, Defines);
- }
-};
-} // end anonymous namespace
-
-namespace {
-// x86-32 Solaris target
-class SolarisX86_32TargetInfo : public X86_32TargetInfo {
-public:
- SolarisX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) {
- UserLabelPrefix = "";
- WCharType = SignedLong;
- // FIXME: WIntType should be SignedLong
- }
- virtual void getTargetDefines(const LangOptions &Opts,
- std::vector<char> &Defines) const {
- X86_32TargetInfo::getTargetDefines(Opts, Defines);
- getSolarisDefines(Opts, Defines);
- }
-};
-} // end anonymous namespace
-
-
-namespace {
// x86-32 Windows target
class WindowsX86_32TargetInfo : public X86_32TargetInfo {
public:
@@ -961,11 +943,11 @@ class X86_64TargetInfo : public X86TargetInfo {
public:
X86_64TargetInfo(const std::string &triple) : X86TargetInfo(triple) {
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
- DoubleAlign = LongLongAlign = 64;
LongDoubleWidth = 128;
LongDoubleAlign = 128;
IntMaxType = SignedLong;
UIntMaxType = UnsignedLong;
+ Int64Type = SignedLong;
RegParmMax = 6;
DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
@@ -978,96 +960,23 @@ public:
" unsigned fp_offset;"
" void* overflow_arg_area;"
" void* reg_save_area;"
- "} __builtin_va_list[1];";
+ "} __va_list_tag;"
+ "typedef __va_list_tag __builtin_va_list[1];";
}
};
} // end anonymous namespace
namespace {
-// x86-64 FreeBSD target
-class FreeBSDX86_64TargetInfo : public X86_64TargetInfo {
+class DarwinX86_64TargetInfo : public DarwinTargetInfo<X86_64TargetInfo> {
public:
- FreeBSDX86_64TargetInfo(const std::string &triple)
- : X86_64TargetInfo(triple) {}
- virtual void getTargetDefines(const LangOptions &Opts,
- std::vector<char> &Defines) const {
- X86_64TargetInfo::getTargetDefines(Opts, Defines);
- getFreeBSDDefines(Opts, 1, getTargetTriple(), Defines);
+ DarwinX86_64TargetInfo(const std::string& triple)
+ : DarwinTargetInfo<X86_64TargetInfo>(triple) {
+ Int64Type = SignedLongLong;
}
};
} // end anonymous namespace
namespace {
-// x86-64 Linux target
-class LinuxX86_64TargetInfo : public X86_64TargetInfo {
-public:
- LinuxX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
- UserLabelPrefix = "";
- }
- virtual void getTargetDefines(const LangOptions &Opts,
- std::vector<char> &Defines) const {
- X86_64TargetInfo::getTargetDefines(Opts, Defines);
- getLinuxDefines(Opts, Defines);
- }
-};
-} // end anonymous namespace
-
-namespace {
-// x86-64 Solaris target
-class SolarisX86_64TargetInfo : public X86_64TargetInfo {
-public:
- SolarisX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
- UserLabelPrefix = "";
- }
- virtual void getTargetDefines(const LangOptions &Opts,
- std::vector<char> &Defines) const {
- X86_64TargetInfo::getTargetDefines(Opts, Defines);
- getSolarisDefines(Opts, Defines);
- }
-};
-} // end anonymous namespace
-
-namespace {
-// x86-64 Darwin (OS X) target
-class DarwinX86_64TargetInfo : public X86_64TargetInfo {
-public:
- DarwinX86_64TargetInfo(const std::string& triple) : X86_64TargetInfo(triple) {
- TLSSupported = false;
- }
-
- virtual const char *getStringSymbolPrefix(bool IsConstant) const {
- return IsConstant ? "\01LC" : "\01lC";
- }
-
- virtual const char *getUnicodeStringSymbolPrefix() const {
- return "__utf16_string_";
- }
-
- virtual const char *getUnicodeStringSection() const {
- return "__TEXT,__ustring";
- }
-
- virtual const char *getCFStringSymbolPrefix() const {
- return "\01L_unnamed_cfstring_";
- }
-
- virtual void getTargetDefines(const LangOptions &Opts,
- std::vector<char> &Defines) const {
- X86_64TargetInfo::getTargetDefines(Opts, Defines);
- getDarwinDefines(Defines, Opts);
- getDarwinOSXDefines(Defines, getTargetTriple());
- }
-
- /// getDefaultLangOptions - Allow the target to specify default settings for
- /// various language options. These may be overridden by command line
- /// options.
- virtual void getDefaultLangOptions(LangOptions &Opts) {
- GetDarwinLanguageOptions(Opts, getTargetTriple());
- }
-};
-} // end anonymous namespace.
-
-namespace {
class ARMTargetInfo : public TargetInfo {
enum {
Armv4t,
@@ -1171,33 +1080,20 @@ public:
namespace {
-class DarwinARMTargetInfo : public ARMTargetInfo {
-public:
- DarwinARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {
- TLSSupported = false;
- }
-
- virtual void getTargetDefines(const LangOptions &Opts,
- std::vector<char> &Defines) const {
- ARMTargetInfo::getTargetDefines(Opts, Defines);
+class DarwinARMTargetInfo :
+ public DarwinTargetInfo<ARMTargetInfo> {
+protected:
+ virtual void getOSDefines(const LangOptions &Opts, const char *Triple,
+ std::vector<char> &Defines) const {
getDarwinDefines(Defines, Opts);
- getDarwinIPhoneOSDefines(Defines, getTargetTriple());
+ getDarwinIPhoneOSDefines(Defines, Triple);
}
-};
-} // end anonymous namespace.
-namespace {
-// arm FreeBSD target
-class FreeBSDARMTargetInfo : public ARMTargetInfo {
public:
- FreeBSDARMTargetInfo(const std::string& triple) : ARMTargetInfo(triple) {}
- virtual void getTargetDefines(const LangOptions &Opts,
- std::vector<char> &Defines) const {
- ARMTargetInfo::getTargetDefines(Opts, Defines);
- getFreeBSDDefines(Opts, 0, getTargetTriple(), Defines);
- }
+ DarwinARMTargetInfo(const std::string& triple)
+ : DarwinTargetInfo<ARMTargetInfo>(triple) {}
};
-} // end anonymous namespace
+} // end anonymous namespace.
namespace {
class SparcV8TargetInfo : public TargetInfo {
@@ -1296,21 +1192,12 @@ void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
} // end anonymous namespace.
namespace {
-class SolarisSparcV8TargetInfo : public SparcV8TargetInfo {
+class SolarisSparcV8TargetInfo : public SolarisTargetInfo<SparcV8TargetInfo> {
public:
SolarisSparcV8TargetInfo(const std::string& triple) :
- SparcV8TargetInfo(triple) {
+ SolarisTargetInfo<SparcV8TargetInfo>(triple) {
SizeType = UnsignedInt;
PtrDiffType = SignedInt;
- WCharType = SignedLong;
- // FIXME: WIntType should be SignedLong
- UserLabelPrefix = "";
- }
-
- virtual void getTargetDefines(const LangOptions &Opts,
- std::vector<char> &Defines) const {
- SparcV8TargetInfo::getTargetDefines(Opts, Defines);
- getSolarisDefines(Opts, Defines);
}
};
} // end anonymous namespace.
@@ -1454,6 +1341,7 @@ TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
// Additions and corrections are welcome.
bool isDarwin = T.find("-darwin") != std::string::npos;
bool isDragonFly = T.find("-dragonfly") != std::string::npos;
+ bool isOpenBSD = T.find("-openbsd") != std::string::npos;
bool isFreeBSD = T.find("-freebsd") != std::string::npos;
bool isSolaris = T.find("-solaris") != std::string::npos;
bool isLinux = T.find("-linux") != std::string::npos;
@@ -1463,13 +1351,13 @@ TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
if (T.find("ppc-") == 0 || T.find("powerpc-") == 0) {
if (isDarwin)
- return new DarwinPPCTargetInfo(T);
+ return new DarwinTargetInfo<PPCTargetInfo>(T);
return new PPC32TargetInfo(T);
}
if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0) {
if (isDarwin)
- return new DarwinPPC64TargetInfo(T);
+ return new DarwinTargetInfo<PPC64TargetInfo>(T);
return new PPC64TargetInfo(T);
}
@@ -1477,7 +1365,7 @@ TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
if (isDarwin)
return new DarwinARMTargetInfo(T);
if (isFreeBSD)
- return new FreeBSDARMTargetInfo(T);
+ return new FreeBSDTargetInfo<ARMTargetInfo>(T);
return new ARMTargetInfo(T);
}
@@ -1491,11 +1379,13 @@ TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
if (isDarwin)
return new DarwinX86_64TargetInfo(T);
if (isLinux)
- return new LinuxX86_64TargetInfo(T);
+ return new LinuxTargetInfo<X86_64TargetInfo>(T);
+ if (isOpenBSD)
+ return new OpenBSDTargetInfo<X86_64TargetInfo>(T);
if (isFreeBSD)
- return new FreeBSDX86_64TargetInfo(T);
+ return new FreeBSDTargetInfo<X86_64TargetInfo>(T);
if (isSolaris)
- return new SolarisX86_64TargetInfo(T);
+ return new SolarisTargetInfo<X86_64TargetInfo>(T);
return new X86_64TargetInfo(T);
}
@@ -1509,13 +1399,15 @@ TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
if (isDarwin)
return new DarwinI386TargetInfo(T);
if (isLinux)
- return new LinuxX86_32TargetInfo(T);
+ return new LinuxTargetInfo<X86_32TargetInfo>(T);
if (isDragonFly)
- return new DragonFlyX86_32TargetInfo(T);
+ return new DragonFlyBSDTargetInfo<X86_32TargetInfo>(T);
+ if (isOpenBSD)
+ return new OpenBSDTargetInfo<X86_32TargetInfo>(T);
if (isFreeBSD)
- return new FreeBSDX86_32TargetInfo(T);
+ return new FreeBSDTargetInfo<X86_32TargetInfo>(T);
if (isSolaris)
- return new SolarisX86_32TargetInfo(T);
+ return new SolarisTargetInfo<X86_32TargetInfo>(T);
if (isWindows)
return new WindowsX86_32TargetInfo(T);
return new X86_32TargetInfo(T);
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index 66b1f17368ea..a919dfa2e32c 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -522,7 +522,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
case Builtin::BIsqrtf:
case Builtin::BIsqrtl: {
// Rewrite sqrt to intrinsic if allowed.
- if (!FD->hasAttr<ConstAttr>(getContext()))
+ if (!FD->hasAttr<ConstAttr>())
break;
Value *Arg0 = EmitScalarExpr(E->getArg(0));
const llvm::Type *ArgType = Arg0->getType();
@@ -534,7 +534,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
case Builtin::BIpowf:
case Builtin::BIpowl: {
// Rewrite sqrt to intrinsic if allowed.
- if (!FD->hasAttr<ConstAttr>(getContext()))
+ if (!FD->hasAttr<ConstAttr>())
break;
Value *Base = EmitScalarExpr(E->getArg(0));
Value *Exponent = EmitScalarExpr(E->getArg(1));
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 4f9a4caee695..5f3acea767d5 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -323,8 +323,8 @@ static bool canGenerateCXXstructor(const CXXRecordDecl *RD,
if (RD->getNumBases() > 0)
return false;
- for (CXXRecordDecl::field_iterator I = RD->field_begin(Context),
- E = RD->field_end(Context); I != E; ++I) {
+ for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
+ I != E; ++I) {
// We don't support ctors for fields that aren't POD.
if (!I->getType()->isPODType())
return false;
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 30c5d28c227e..97391bc620be 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -142,8 +142,8 @@ void CodeGenTypes::GetExpandedTypes(QualType Ty,
assert(!RD->hasFlexibleArrayMember() &&
"Cannot expand structure with flexible array.");
- for (RecordDecl::field_iterator i = RD->field_begin(Context),
- e = RD->field_end(Context); i != e; ++i) {
+ for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
+ i != e; ++i) {
const FieldDecl *FD = *i;
assert(!FD->isBitField() &&
"Cannot expand structure with bit-field members.");
@@ -167,8 +167,8 @@ CodeGenFunction::ExpandTypeFromArgs(QualType Ty, LValue LV,
assert(LV.isSimple() &&
"Unexpected non-simple lvalue during struct expansion.");
llvm::Value *Addr = LV.getAddress();
- for (RecordDecl::field_iterator i = RD->field_begin(getContext()),
- e = RD->field_end(getContext()); i != e; ++i) {
+ for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
+ i != e; ++i) {
FieldDecl *FD = *i;
QualType FT = FD->getType();
@@ -194,8 +194,8 @@ CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV,
RecordDecl *RD = RT->getDecl();
assert(RV.isAggregate() && "Unexpected rvalue during struct expansion");
llvm::Value *Addr = RV.getAggregateAddr();
- for (RecordDecl::field_iterator i = RD->field_begin(getContext()),
- e = RD->field_end(getContext()); i != e; ++i) {
+ for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
+ i != e; ++i) {
FieldDecl *FD = *i;
QualType FT = FD->getType();
@@ -377,13 +377,13 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
// FIXME: handle sseregparm someday...
if (TargetDecl) {
- if (TargetDecl->hasAttr<NoThrowAttr>(getContext()))
+ if (TargetDecl->hasAttr<NoThrowAttr>())
FuncAttrs |= llvm::Attribute::NoUnwind;
- if (TargetDecl->hasAttr<NoReturnAttr>(getContext()))
+ if (TargetDecl->hasAttr<NoReturnAttr>())
FuncAttrs |= llvm::Attribute::NoReturn;
- if (TargetDecl->hasAttr<ConstAttr>(getContext()))
+ if (TargetDecl->hasAttr<ConstAttr>())
FuncAttrs |= llvm::Attribute::ReadNone;
- else if (TargetDecl->hasAttr<PureAttr>(getContext()))
+ else if (TargetDecl->hasAttr<PureAttr>())
FuncAttrs |= llvm::Attribute::ReadOnly;
}
@@ -392,6 +392,11 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
if (CompileOpts.NoImplicitFloat)
FuncAttrs |= llvm::Attribute::NoImplicitFloat;
+ if (Features.getStackProtectorMode() == LangOptions::SSPOn)
+ FuncAttrs |= llvm::Attribute::StackProtect;
+ else if (Features.getStackProtectorMode() == LangOptions::SSPReq)
+ FuncAttrs |= llvm::Attribute::StackProtectReq;
+
QualType RetTy = FI.getReturnType();
unsigned Index = 1;
const ABIArgInfo &RetAI = FI.getReturnInfo();
@@ -433,7 +438,7 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
signed RegParm = 0;
if (TargetDecl)
if (const RegparmAttr *RegParmAttr
- = TargetDecl->getAttr<RegparmAttr>(getContext()))
+ = TargetDecl->getAttr<RegparmAttr>())
RegParm = RegParmAttr->getNumParams();
unsigned PointerWidth = getContext().Target.getPointerWidth(0);
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 5e872c290dfa..2bf8a222a253 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -151,7 +151,7 @@ llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT,
uint64_t Offset = 0;
return DebugFactory.CreateBasicType(Unit,
- BT->getName(M->getContext().getLangOptions().CPlusPlus),
+ BT->getName(M->getContext().getLangOptions()),
Unit, 0, Size, Align,
Offset, /*flags*/ 0, Encoding);
}
@@ -437,8 +437,8 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty,
const ASTRecordLayout &RL = M->getContext().getASTRecordLayout(Decl);
unsigned FieldNo = 0;
- for (RecordDecl::field_iterator I = Decl->field_begin(M->getContext()),
- E = Decl->field_end(M->getContext());
+ for (RecordDecl::field_iterator I = Decl->field_begin(),
+ E = Decl->field_end();
I != E; ++I, ++FieldNo) {
FieldDecl *Field = *I;
llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);
@@ -638,8 +638,7 @@ llvm::DIType CGDebugInfo::CreateType(const EnumType *Ty,
// Create DIEnumerator elements for each enumerator.
for (EnumDecl::enumerator_iterator
- Enum = Decl->enumerator_begin(M->getContext()),
- EnumEnd = Decl->enumerator_end(M->getContext());
+ Enum = Decl->enumerator_begin(), EnumEnd = Decl->enumerator_end();
Enum != EnumEnd; ++Enum) {
Enumerators.push_back(DebugFactory.CreateEnumerator(Enum->getNameAsString(),
Enum->getInitVal().getZExtValue()));
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index f97c62f9d142..2ae7e225ebbf 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -60,7 +60,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) {
/// EmitBlockVarDecl - This method handles emission of any variable declaration
/// inside a function, including static vars etc.
void CodeGenFunction::EmitBlockVarDecl(const VarDecl &D) {
- if (D.hasAttr<AsmLabelAttr>(getContext()))
+ if (D.hasAttr<AsmLabelAttr>())
CGM.ErrorUnsupported(&D, "__asm__");
switch (D.getStorageClass()) {
@@ -171,7 +171,7 @@ void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D) {
}
// FIXME: Merge attribute handling.
- if (const AnnotateAttr *AA = D.getAttr<AnnotateAttr>(getContext())) {
+ if (const AnnotateAttr *AA = D.getAttr<AnnotateAttr>()) {
SourceManager &SM = CGM.getContext().getSourceManager();
llvm::Constant *Ann =
CGM.EmitAnnotateAttr(GV, AA,
@@ -179,10 +179,10 @@ void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D) {
CGM.AddAnnotation(Ann);
}
- if (const SectionAttr *SA = D.getAttr<SectionAttr>(getContext()))
+ if (const SectionAttr *SA = D.getAttr<SectionAttr>())
GV->setSection(SA->getName());
- if (D.hasAttr<UsedAttr>(getContext()))
+ if (D.hasAttr<UsedAttr>())
CGM.AddUsedGlobal(GV);
// We may have to cast the constant because of the initializer
@@ -244,7 +244,7 @@ const llvm::Type *CodeGenFunction::BuildByRefType(QualType Ty,
/// These turn into simple stack objects, or GlobalValues depending on target.
void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
QualType Ty = D.getType();
- bool isByRef = D.hasAttr<BlocksAttr>(getContext());
+ bool isByRef = D.hasAttr<BlocksAttr>();
bool needsDispose = false;
unsigned Align = 0;
@@ -414,7 +414,7 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
}
// Handle the cleanup attribute
- if (const CleanupAttr *CA = D.getAttr<CleanupAttr>(getContext())) {
+ if (const CleanupAttr *CA = D.getAttr<CleanupAttr>()) {
const FunctionDecl *FD = CA->getFunctionDecl();
llvm::Constant* F = CGM.GetAddrOfFunction(GlobalDecl(FD));
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index a21140765c20..0951019f0108 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -670,7 +670,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
isa<ImplicitParamDecl>(VD))) {
LValue LV;
bool NonGCable = VD->hasLocalStorage() &&
- !VD->hasAttr<BlocksAttr>(getContext());
+ !VD->hasAttr<BlocksAttr>();
if (VD->hasExternalStorage()) {
llvm::Value *V = CGM.GetAddrOfGlobalVar(VD);
if (VD->getType()->isReferenceType())
@@ -686,7 +686,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
// local static?
if (!NonGCable)
attr = getContext().getObjCGCAttrKind(E->getType());
- if (VD->hasAttr<BlocksAttr>(getContext())) {
+ if (VD->hasAttr<BlocksAttr>()) {
bool needsCopyDispose = BlockRequiresCopying(VD->getType());
const llvm::Type *PtrStructTy = V->getType();
const llvm::Type *Ty = PtrStructTy;
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index 4268ae3b1701..412a06594f53 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -436,8 +436,8 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
#ifndef NDEBUG
// Make sure that it's really an empty and not a failure of
// semantic analysis.
- for (RecordDecl::field_iterator Field = SD->field_begin(CGF.getContext()),
- FieldEnd = SD->field_end(CGF.getContext());
+ for (RecordDecl::field_iterator Field = SD->field_begin(),
+ FieldEnd = SD->field_end();
Field != FieldEnd; ++Field)
assert(Field->isUnnamedBitfield() && "Only unnamed bitfields allowed");
#endif
@@ -461,8 +461,8 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
// Here we iterate over the fields; this makes it simpler to both
// default-initialize fields and skip over unnamed fields.
- for (RecordDecl::field_iterator Field = SD->field_begin(CGF.getContext()),
- FieldEnd = SD->field_end(CGF.getContext());
+ for (RecordDecl::field_iterator Field = SD->field_begin(),
+ FieldEnd = SD->field_end();
Field != FieldEnd; ++Field) {
// We're done once we hit the flexible array member
if (Field->getType()->isIncompleteArrayType())
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp
index 0b109f9bee42..37c9c366fee6 100644
--- a/lib/CodeGen/CGExprConstant.cpp
+++ b/lib/CodeGen/CGExprConstant.cpp
@@ -199,8 +199,8 @@ public:
// Copy initializer elements. Skip padding fields.
unsigned EltNo = 0; // Element no in ILE
bool RewriteType = false;
- for (RecordDecl::field_iterator Field = RD->field_begin(CGM.getContext()),
- FieldEnd = RD->field_end(CGM.getContext());
+ for (RecordDecl::field_iterator Field = RD->field_begin(),
+ FieldEnd = RD->field_end();
EltNo < ILE->getNumInits() && Field != FieldEnd; ++Field) {
if (Field->isBitField()) {
if (!Field->getIdentifier())
@@ -263,8 +263,8 @@ public:
// Make sure that it's really an empty and not a failure of
// semantic analysis.
RecordDecl *RD = ILE->getType()->getAsRecordType()->getDecl();
- for (RecordDecl::field_iterator Field = RD->field_begin(CGM.getContext()),
- FieldEnd = RD->field_end(CGM.getContext());
+ for (RecordDecl::field_iterator Field = RD->field_begin(),
+ FieldEnd = RD->field_end();
Field != FieldEnd; ++Field)
assert(Field->isUnnamedBitfield() && "Only unnamed bitfields allowed");
#endif
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index e7cf8e6e653a..33cb5bca3869 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -126,11 +126,11 @@ void CodeGenFunction::StartObjCMethod(const ObjCMethodDecl *OMD,
/// its pointer, name, and types registered in the class struture.
void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
// Check if we should generate debug info for this method.
- if (CGM.getDebugInfo() && !OMD->hasAttr<NodebugAttr>(getContext()))
+ if (CGM.getDebugInfo() && !OMD->hasAttr<NodebugAttr>())
DebugInfo = CGM.getDebugInfo();
StartObjCMethod(OMD, OMD->getClassInterface());
- EmitStmt(OMD->getBody(getContext()));
- FinishFunction(OMD->getBodyRBrace(getContext()));
+ EmitStmt(OMD->getBody());
+ FinishFunction(OMD->getBodyRBrace());
}
// FIXME: I wasn't sure about the synthesis approach. If we end up generating an
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index 4f96b8baec06..6554da9cf98c 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -180,7 +180,7 @@ void CGObjCGNU::EmitClassRef(const std::string &className){
std::string symbolName = "__objc_class_name_" + className;
llvm::GlobalVariable *ClassSymbol = TheModule.getGlobalVariable(symbolName);
if (!ClassSymbol) {
- ClassSymbol = new llvm::GlobalVariable(LongTy, false,
+ ClassSymbol = new llvm::GlobalVariable(LongTy, false,
llvm::GlobalValue::ExternalLinkage, 0, symbolName, &TheModule);
}
new llvm::GlobalVariable(ClassSymbol->getType(), true,
@@ -739,8 +739,8 @@ void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) {
Protocols.push_back((*PI)->getNameAsString());
llvm::SmallVector<llvm::Constant*, 16> InstanceMethodNames;
llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
- for (ObjCProtocolDecl::instmeth_iterator iter = PD->instmeth_begin(Context),
- E = PD->instmeth_end(Context); iter != E; iter++) {
+ for (ObjCProtocolDecl::instmeth_iterator iter = PD->instmeth_begin(),
+ E = PD->instmeth_end(); iter != E; iter++) {
std::string TypeStr;
Context.getObjCEncodingForMethodDecl(*iter, TypeStr);
InstanceMethodNames.push_back(
@@ -751,8 +751,8 @@ void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) {
llvm::SmallVector<llvm::Constant*, 16> ClassMethodNames;
llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
for (ObjCProtocolDecl::classmeth_iterator
- iter = PD->classmeth_begin(Context),
- endIter = PD->classmeth_end(Context) ; iter != endIter ; iter++) {
+ iter = PD->classmeth_begin(), endIter = PD->classmeth_end();
+ iter != endIter ; iter++) {
std::string TypeStr;
Context.getObjCEncodingForMethodDecl((*iter),TypeStr);
ClassMethodNames.push_back(
@@ -794,8 +794,7 @@ void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
llvm::SmallVector<Selector, 16> InstanceMethodSels;
llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
for (ObjCCategoryImplDecl::instmeth_iterator
- iter = OCD->instmeth_begin(CGM.getContext()),
- endIter = OCD->instmeth_end(CGM.getContext());
+ iter = OCD->instmeth_begin(), endIter = OCD->instmeth_end();
iter != endIter ; iter++) {
InstanceMethodSels.push_back((*iter)->getSelector());
std::string TypeStr;
@@ -807,8 +806,7 @@ void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
llvm::SmallVector<Selector, 16> ClassMethodSels;
llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
for (ObjCCategoryImplDecl::classmeth_iterator
- iter = OCD->classmeth_begin(CGM.getContext()),
- endIter = OCD->classmeth_end(CGM.getContext());
+ iter = OCD->classmeth_begin(), endIter = OCD->classmeth_end();
iter != endIter ; iter++) {
ClassMethodSels.push_back((*iter)->getSelector());
std::string TypeStr;
@@ -861,9 +859,14 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
std::string ClassName = ClassDecl->getNameAsString();
// Emit the symbol that is used to generate linker errors if this class is
// referenced in other modules but not declared.
- new llvm::GlobalVariable(LongTy, false, llvm::GlobalValue::ExternalLinkage,
- llvm::ConstantInt::get(LongTy, 0), "__objc_class_name_" + ClassName,
- &TheModule);
+ std::string classSymbolName = "__objc_class_name_" + ClassName;
+ if (llvm::GlobalVariable *symbol =
+ TheModule.getGlobalVariable(classSymbolName)) {
+ symbol->setInitializer(llvm::ConstantInt::get(LongTy, 0));
+ } else {
+ new llvm::GlobalVariable(LongTy, false, llvm::GlobalValue::ExternalLinkage,
+ llvm::ConstantInt::get(LongTy, 0), classSymbolName, &TheModule);
+ }
// Get the size of instances.
int instanceSize = Context.getASTObjCImplementationLayout(OID).getSize() / 8;
@@ -906,8 +909,7 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
llvm::SmallVector<Selector, 16> InstanceMethodSels;
llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
for (ObjCImplementationDecl::instmeth_iterator
- iter = OID->instmeth_begin(CGM.getContext()),
- endIter = OID->instmeth_end(CGM.getContext());
+ iter = OID->instmeth_begin(), endIter = OID->instmeth_end();
iter != endIter ; iter++) {
InstanceMethodSels.push_back((*iter)->getSelector());
std::string TypeStr;
@@ -915,8 +917,7 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
InstanceMethodTypes.push_back(CGM.GetAddrOfConstantCString(TypeStr));
}
for (ObjCImplDecl::propimpl_iterator
- iter = OID->propimpl_begin(CGM.getContext()),
- endIter = OID->propimpl_end(CGM.getContext());
+ iter = OID->propimpl_begin(), endIter = OID->propimpl_end();
iter != endIter ; iter++) {
ObjCPropertyDecl *property = (*iter)->getPropertyDecl();
if (ObjCMethodDecl *getter = property->getGetterMethodDecl()) {
@@ -937,8 +938,7 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
llvm::SmallVector<Selector, 16> ClassMethodSels;
llvm::SmallVector<llvm::Constant*, 16> ClassMethodTypes;
for (ObjCImplementationDecl::classmeth_iterator
- iter = OID->classmeth_begin(CGM.getContext()),
- endIter = OID->classmeth_end(CGM.getContext());
+ iter = OID->classmeth_begin(), endIter = OID->classmeth_end();
iter != endIter ; iter++) {
ClassMethodSels.push_back((*iter)->getSelector());
std::string TypeStr;
@@ -1163,9 +1163,8 @@ llvm::Function *CGObjCGNU::ModuleInitFunction() {
// Create the load function calling the runtime entry point with the module
// structure
- std::vector<const llvm::Type*> VoidArgs;
llvm::Function * LoadFunction = llvm::Function::Create(
- llvm::FunctionType::get(llvm::Type::VoidTy, VoidArgs, false),
+ llvm::FunctionType::get(llvm::Type::VoidTy, false),
llvm::GlobalValue::InternalLinkage, ".objc_load_function",
&TheModule);
llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", LoadFunction);
@@ -1250,7 +1249,7 @@ void CGObjCGNU::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
// Pointer to the personality function
llvm::Constant *Personality =
CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::Int32Ty,
- std::vector<const llvm::Type*>(), true),
+ true),
"__gnu_objc_personality_v0");
Personality = llvm::ConstantExpr::getBitCast(Personality, PtrTy);
std::vector<const llvm::Type*> Params;
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 865e8c240be2..c3354574c775 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -690,7 +690,6 @@ public:
llvm::Value *getEHPersonalityPtr() {
llvm::Constant *Personality =
CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::Int32Ty,
- std::vector<const llvm::Type*>(),
true),
"__objc_personality_v0");
return llvm::ConstantExpr::getBitCast(Personality, Int8PtrTy);
@@ -705,9 +704,8 @@ public:
}
llvm::Constant *getObjCEndCatchFn() {
- std::vector<const llvm::Type*> Params;
return CGM.CreateRuntimeFunction(llvm::FunctionType::get(llvm::Type::VoidTy,
- Params, false),
+ false),
"objc_end_catch");
}
@@ -1360,7 +1358,7 @@ static llvm::Constant *getConstantGEP(llvm::Constant *C,
/// class has the __objc_exception__ attribute.
static bool hasObjCExceptionAttribute(ASTContext &Context,
const ObjCInterfaceDecl *OID) {
- if (OID->hasAttr<ObjCExceptionAttr>(Context))
+ if (OID->hasAttr<ObjCExceptionAttr>())
return true;
if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
return hasObjCExceptionAttribute(Context, Super);
@@ -1585,8 +1583,7 @@ llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
for (ObjCProtocolDecl::instmeth_iterator
- i = PD->instmeth_begin(CGM.getContext()),
- e = PD->instmeth_end(CGM.getContext()); i != e; ++i) {
+ i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
ObjCMethodDecl *MD = *i;
llvm::Constant *C = GetMethodDescriptionConstant(MD);
if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
@@ -1597,8 +1594,7 @@ llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
}
for (ObjCProtocolDecl::classmeth_iterator
- i = PD->classmeth_begin(CGM.getContext()),
- e = PD->classmeth_end(CGM.getContext()); i != e; ++i) {
+ i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
ObjCMethodDecl *MD = *i;
llvm::Constant *C = GetMethodDescriptionConstant(MD);
if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
@@ -1772,8 +1768,8 @@ llvm::Constant *CGObjCCommonMac::EmitPropertyList(const std::string &Name,
const ObjCContainerDecl *OCD,
const ObjCCommonTypesHelper &ObjCTypes) {
std::vector<llvm::Constant*> Properties, Prop(2);
- for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(CGM.getContext()),
- E = OCD->prop_end(CGM.getContext()); I != E; ++I) {
+ for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(),
+ E = OCD->prop_end(); I != E; ++I) {
const ObjCPropertyDecl *PD = *I;
Prop[0] = GetPropertyName(PD->getIdentifier());
Prop[1] = GetPropertyTypeString(PD, Container);
@@ -1865,14 +1861,12 @@ void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
for (ObjCCategoryImplDecl::instmeth_iterator
- i = OCD->instmeth_begin(CGM.getContext()),
- e = OCD->instmeth_end(CGM.getContext()); i != e; ++i) {
+ i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
// Instance methods should always be defined.
InstanceMethods.push_back(GetMethodConstant(*i));
}
for (ObjCCategoryImplDecl::classmeth_iterator
- i = OCD->classmeth_begin(CGM.getContext()),
- e = OCD->classmeth_end(CGM.getContext()); i != e; ++i) {
+ i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
// Class methods should always be defined.
ClassMethods.push_back(GetMethodConstant(*i));
}
@@ -1969,21 +1963,18 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
for (ObjCImplementationDecl::instmeth_iterator
- i = ID->instmeth_begin(CGM.getContext()),
- e = ID->instmeth_end(CGM.getContext()); i != e; ++i) {
+ i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
// Instance methods should always be defined.
InstanceMethods.push_back(GetMethodConstant(*i));
}
for (ObjCImplementationDecl::classmeth_iterator
- i = ID->classmeth_begin(CGM.getContext()),
- e = ID->classmeth_end(CGM.getContext()); i != e; ++i) {
+ i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
// Class methods should always be defined.
ClassMethods.push_back(GetMethodConstant(*i));
}
for (ObjCImplementationDecl::propimpl_iterator
- i = ID->propimpl_begin(CGM.getContext()),
- e = ID->propimpl_end(CGM.getContext()); i != e; ++i) {
+ i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
ObjCPropertyImplDecl *PID = *i;
if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) {
@@ -2983,8 +2974,7 @@ void CGObjCCommonMac::BuildAggrIvarRecordLayout(const RecordType *RT,
bool &HasUnion) {
const RecordDecl *RD = RT->getDecl();
// FIXME - Use iterator.
- llvm::SmallVector<FieldDecl*, 16> Fields(RD->field_begin(CGM.getContext()),
- RD->field_end(CGM.getContext()));
+ llvm::SmallVector<FieldDecl*, 16> Fields(RD->field_begin(), RD->field_end());
const llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
const llvm::StructLayout *RecLayout =
CGM.getTargetData().getStructLayout(cast<llvm::StructType>(Ty));
@@ -3528,9 +3518,9 @@ ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0,
SourceLocation(),
&Ctx.Idents.get("_objc_super"));
- RD->addDecl(Ctx, FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
+ RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
Ctx.getObjCIdType(), 0, false));
- RD->addDecl(Ctx, FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
+ RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
Ctx.getObjCClassType(), 0, false));
RD->completeDefinition(Ctx);
@@ -3987,9 +3977,9 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul
RecordDecl *RD = RecordDecl::Create(Ctx, TagDecl::TK_struct, 0,
SourceLocation(),
&Ctx.Idents.get("_message_ref_t"));
- RD->addDecl(Ctx, FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
+ RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
Ctx.VoidPtrTy, 0, false));
- RD->addDecl(Ctx, FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
+ RD->addDecl(FieldDecl::Create(Ctx, RD, SourceLocation(), 0,
Ctx.getObjCSelType(), 0, false));
RD->completeDefinition(Ctx);
@@ -4190,22 +4180,19 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
if (flags & CLS_META) {
MethodListName += "CLASS_METHODS_" + ID->getNameAsString();
for (ObjCImplementationDecl::classmeth_iterator
- i = ID->classmeth_begin(CGM.getContext()),
- e = ID->classmeth_end(CGM.getContext()); i != e; ++i) {
+ i = ID->classmeth_begin(), e = ID->classmeth_end(); i != e; ++i) {
// Class methods should always be defined.
Methods.push_back(GetMethodConstant(*i));
}
} else {
MethodListName += "INSTANCE_METHODS_" + ID->getNameAsString();
for (ObjCImplementationDecl::instmeth_iterator
- i = ID->instmeth_begin(CGM.getContext()),
- e = ID->instmeth_end(CGM.getContext()); i != e; ++i) {
+ i = ID->instmeth_begin(), e = ID->instmeth_end(); i != e; ++i) {
// Instance methods should always be defined.
Methods.push_back(GetMethodConstant(*i));
}
for (ObjCImplementationDecl::propimpl_iterator
- i = ID->propimpl_begin(CGM.getContext()),
- e = ID->propimpl_end(CGM.getContext()); i != e; ++i) {
+ i = ID->propimpl_begin(), e = ID->propimpl_end(); i != e; ++i) {
ObjCPropertyImplDecl *PID = *i;
if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
@@ -4298,7 +4285,7 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData(
bool
CGObjCNonFragileABIMac::ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
- return OD->getClassMethod(CGM.getContext(), GetNullarySelector("load")) != 0;
+ return OD->getClassMethod(GetNullarySelector("load")) != 0;
}
void CGObjCNonFragileABIMac::GetClassSizeInfo(const ObjCImplementationDecl *OID,
@@ -4478,8 +4465,7 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
"_$_" + OCD->getNameAsString();
for (ObjCCategoryImplDecl::instmeth_iterator
- i = OCD->instmeth_begin(CGM.getContext()),
- e = OCD->instmeth_end(CGM.getContext()); i != e; ++i) {
+ i = OCD->instmeth_begin(), e = OCD->instmeth_end(); i != e; ++i) {
// Instance methods should always be defined.
Methods.push_back(GetMethodConstant(*i));
}
@@ -4493,8 +4479,7 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
OCD->getNameAsString();
Methods.clear();
for (ObjCCategoryImplDecl::classmeth_iterator
- i = OCD->classmeth_begin(CGM.getContext()),
- e = OCD->classmeth_end(CGM.getContext()); i != e; ++i) {
+ i = OCD->classmeth_begin(), e = OCD->classmeth_end(); i != e; ++i) {
// Class methods should always be defined.
Methods.push_back(GetMethodConstant(*i));
}
@@ -4782,9 +4767,7 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
std::vector<llvm::Constant*> OptInstanceMethods, OptClassMethods;
for (ObjCProtocolDecl::instmeth_iterator
- i = PD->instmeth_begin(CGM.getContext()),
- e = PD->instmeth_end(CGM.getContext());
- i != e; ++i) {
+ i = PD->instmeth_begin(), e = PD->instmeth_end(); i != e; ++i) {
ObjCMethodDecl *MD = *i;
llvm::Constant *C = GetMethodDescriptionConstant(MD);
if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
@@ -4795,9 +4778,7 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
}
for (ObjCProtocolDecl::classmeth_iterator
- i = PD->classmeth_begin(CGM.getContext()),
- e = PD->classmeth_end(CGM.getContext());
- i != e; ++i) {
+ i = PD->classmeth_begin(), e = PD->classmeth_end(); i != e; ++i) {
ObjCMethodDecl *MD = *i;
llvm::Constant *C = GetMethodDescriptionConstant(MD);
if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index f10a08f9db86..c3f9364e7ae4 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -199,7 +199,7 @@ void CodeGenFunction::StartFunction(const Decl *D, QualType RetTy,
void CodeGenFunction::GenerateCode(const FunctionDecl *FD,
llvm::Function *Fn) {
// Check if we should generate debug info for this function.
- if (CGM.getDebugInfo() && !FD->hasAttr<NodebugAttr>(getContext()))
+ if (CGM.getDebugInfo() && !FD->hasAttr<NodebugAttr>())
DebugInfo = CGM.getDebugInfo();
FunctionArgList Args;
@@ -226,7 +226,7 @@ void CodeGenFunction::GenerateCode(const FunctionDecl *FD,
}
// FIXME: Support CXXTryStmt here, too.
- if (const CompoundStmt *S = FD->getCompoundBody(getContext())) {
+ if (const CompoundStmt *S = FD->getCompoundBody()) {
StartFunction(FD, FD->getResultType(), Fn, Args, S->getLBracLoc());
EmitStmt(S);
FinishFunction(S->getRBracLoc());
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 0a531e9b21a6..d88a37a45b23 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -102,7 +102,7 @@ CodeGenModule::getDeclVisibilityMode(const Decl *D) const {
if (VD->getStorageClass() == VarDecl::PrivateExtern)
return LangOptions::Hidden;
- if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>(getContext())) {
+ if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>()) {
switch (attr->getVisibility()) {
default: assert(0 && "Unknown visibility!");
case VisibilityAttr::DefaultVisibility:
@@ -243,12 +243,20 @@ void CodeGenModule::EmitAnnotations() {
static CodeGenModule::GVALinkage
GetLinkageForFunction(ASTContext &Context, const FunctionDecl *FD,
const LangOptions &Features) {
+ // The kind of external linkage this function will have, if it is not
+ // inline or static.
+ CodeGenModule::GVALinkage External = CodeGenModule::GVA_StrongExternal;
+ if (Context.getLangOptions().CPlusPlus &&
+ (FD->getPrimaryTemplate() || FD->getInstantiatedFromMemberFunction()) &&
+ !FD->isExplicitSpecialization())
+ External = CodeGenModule::GVA_TemplateInstantiation;
+
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
// C++ member functions defined inside the class are always inline.
if (MD->isInline() || !MD->isOutOfLine())
return CodeGenModule::GVA_CXXInline;
- return CodeGenModule::GVA_StrongExternal;
+ return External;
}
// "static" functions get internal linkage.
@@ -256,7 +264,7 @@ GetLinkageForFunction(ASTContext &Context, const FunctionDecl *FD,
return CodeGenModule::GVA_Internal;
if (!FD->isInline())
- return CodeGenModule::GVA_StrongExternal;
+ return External;
// If the inline function explicitly has the GNU inline attribute on it, or if
// this is C89 mode, we use to GNU semantics.
@@ -273,7 +281,7 @@ GetLinkageForFunction(ASTContext &Context, const FunctionDecl *FD,
if (FD->isExternGNUInline(Context))
return CodeGenModule::GVA_C99Inline;
// Normal inline is a strong symbol.
- return CodeGenModule::GVA_StrongExternal;
+ return External;
}
// The definition of inline changes based on the language. Note that we
@@ -298,15 +306,15 @@ void CodeGenModule::SetFunctionDefinitionAttributes(const FunctionDecl *D,
if (Linkage == GVA_Internal) {
GV->setLinkage(llvm::Function::InternalLinkage);
- } else if (D->hasAttr<DLLExportAttr>(getContext())) {
+ } else if (D->hasAttr<DLLExportAttr>()) {
GV->setLinkage(llvm::Function::DLLExportLinkage);
- } else if (D->hasAttr<WeakAttr>(getContext())) {
+ } else if (D->hasAttr<WeakAttr>()) {
GV->setLinkage(llvm::Function::WeakAnyLinkage);
} else if (Linkage == GVA_C99Inline) {
// In C99 mode, 'inline' functions are guaranteed to have a strong
// definition somewhere else, so we can use available_externally linkage.
GV->setLinkage(llvm::Function::AvailableExternallyLinkage);
- } else if (Linkage == GVA_CXXInline) {
+ } else if (Linkage == GVA_CXXInline || Linkage == GVA_TemplateInstantiation) {
// In C++, the compiler has to emit a definition in every translation unit
// that references the function. We should use linkonce_odr because
// a) if all references in this translation unit are optimized away, we
@@ -333,10 +341,10 @@ void CodeGenModule::SetLLVMFunctionAttributes(const Decl *D,
AttributeList.size()));
// Set the appropriate calling convention for the Function.
- if (D->hasAttr<FastCallAttr>(getContext()))
+ if (D->hasAttr<FastCallAttr>())
F->setCallingConv(llvm::CallingConv::X86_FastCall);
- if (D->hasAttr<StdCallAttr>(getContext()))
+ if (D->hasAttr<StdCallAttr>())
F->setCallingConv(llvm::CallingConv::X86_StdCall);
}
@@ -345,10 +353,10 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
if (!Features.Exceptions && !Features.ObjCNonFragileABI)
F->addFnAttr(llvm::Attribute::NoUnwind);
- if (D->hasAttr<AlwaysInlineAttr>(getContext()))
+ if (D->hasAttr<AlwaysInlineAttr>())
F->addFnAttr(llvm::Attribute::AlwaysInline);
- if (D->hasAttr<NoinlineAttr>(getContext()))
+ if (D->hasAttr<NoinlineAttr>())
F->addFnAttr(llvm::Attribute::NoInline);
}
@@ -356,10 +364,10 @@ void CodeGenModule::SetCommonAttributes(const Decl *D,
llvm::GlobalValue *GV) {
setGlobalVisibility(GV, D);
- if (D->hasAttr<UsedAttr>(getContext()))
+ if (D->hasAttr<UsedAttr>())
AddUsedGlobal(GV);
- if (const SectionAttr *SA = D->getAttr<SectionAttr>(getContext()))
+ if (const SectionAttr *SA = D->getAttr<SectionAttr>())
GV->setSection(SA->getName());
}
@@ -383,10 +391,10 @@ void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD,
// Only a few attributes are set on declarations; these may later be
// overridden by a definition.
- if (FD->hasAttr<DLLImportAttr>(getContext())) {
+ if (FD->hasAttr<DLLImportAttr>()) {
F->setLinkage(llvm::Function::DLLImportLinkage);
- } else if (FD->hasAttr<WeakAttr>(getContext()) ||
- FD->hasAttr<WeakImportAttr>(getContext())) {
+ } else if (FD->hasAttr<WeakAttr>() ||
+ FD->hasAttr<WeakImportAttr>()) {
// "extern_weak" is overloaded in LLVM; we probably should have
// separate linkage types for this.
F->setLinkage(llvm::Function::ExternalWeakLinkage);
@@ -394,7 +402,7 @@ void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD,
F->setLinkage(llvm::Function::ExternalLinkage);
}
- if (const SectionAttr *SA = FD->getAttr<SectionAttr>(getContext()))
+ if (const SectionAttr *SA = FD->getAttr<SectionAttr>())
F->setSection(SA->getName());
}
@@ -508,13 +516,13 @@ llvm::Constant *CodeGenModule::EmitAnnotateAttr(llvm::GlobalValue *GV,
bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) {
// Never defer when EmitAllDecls is specified or the decl has
// attribute used.
- if (Features.EmitAllDecls || Global->hasAttr<UsedAttr>(getContext()))
+ if (Features.EmitAllDecls || Global->hasAttr<UsedAttr>())
return false;
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Global)) {
// Constructors and destructors should never be deferred.
- if (FD->hasAttr<ConstructorAttr>(getContext()) ||
- FD->hasAttr<DestructorAttr>(getContext()))
+ if (FD->hasAttr<ConstructorAttr>() ||
+ FD->hasAttr<DestructorAttr>())
return false;
GVALinkage Linkage = GetLinkageForFunction(getContext(), FD, Features);
@@ -538,7 +546,7 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
// If this is an alias definition (which otherwise looks like a declaration)
// emit it now.
- if (Global->hasAttr<AliasAttr>(getContext()))
+ if (Global->hasAttr<AliasAttr>())
return EmitAliasDefinition(Global);
// Ignore declarations, they will be emitted on their first use.
@@ -727,8 +735,8 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMGlobal(const char *MangledName,
if (D->getStorageClass() == VarDecl::PrivateExtern)
GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
- if (D->hasAttr<WeakAttr>(getContext()) ||
- D->hasAttr<WeakImportAttr>(getContext()))
+ if (D->hasAttr<WeakAttr>() ||
+ D->hasAttr<WeakImportAttr>())
GV->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
GV->setThreadLocal(D->isThreadSpecified());
@@ -848,7 +856,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
cast<llvm::GlobalValue>(Entry)->eraseFromParent();
}
- if (const AnnotateAttr *AA = D->getAttr<AnnotateAttr>(getContext())) {
+ if (const AnnotateAttr *AA = D->getAttr<AnnotateAttr>()) {
SourceManager &SM = Context.getSourceManager();
AddAnnotation(EmitAnnotateAttr(GV, AA,
SM.getInstantiationLineNumber(D->getLocation())));
@@ -861,11 +869,11 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
// Set the llvm linkage type as appropriate.
if (D->getStorageClass() == VarDecl::Static)
GV->setLinkage(llvm::Function::InternalLinkage);
- else if (D->hasAttr<DLLImportAttr>(getContext()))
+ else if (D->hasAttr<DLLImportAttr>())
GV->setLinkage(llvm::Function::DLLImportLinkage);
- else if (D->hasAttr<DLLExportAttr>(getContext()))
+ else if (D->hasAttr<DLLExportAttr>())
GV->setLinkage(llvm::Function::DLLExportLinkage);
- else if (D->hasAttr<WeakAttr>(getContext()))
+ else if (D->hasAttr<WeakAttr>())
GV->setLinkage(llvm::GlobalVariable::WeakAnyLinkage);
else if (!CompileOpts.NoCommon &&
(!D->hasExternalStorage() && !D->getInit()))
@@ -1028,14 +1036,14 @@ void CodeGenModule::EmitGlobalFunctionDefinition(GlobalDecl GD) {
SetFunctionDefinitionAttributes(D, Fn);
SetLLVMFunctionAttributesForDefinition(D, Fn);
- if (const ConstructorAttr *CA = D->getAttr<ConstructorAttr>(getContext()))
+ if (const ConstructorAttr *CA = D->getAttr<ConstructorAttr>())
AddGlobalCtor(Fn, CA->getPriority());
- if (const DestructorAttr *DA = D->getAttr<DestructorAttr>(getContext()))
+ if (const DestructorAttr *DA = D->getAttr<DestructorAttr>())
AddGlobalDtor(Fn, DA->getPriority());
}
void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) {
- const AliasAttr *AA = D->getAttr<AliasAttr>(getContext());
+ const AliasAttr *AA = D->getAttr<AliasAttr>();
assert(AA && "Not an alias?");
const llvm::Type *DeclTy = getTypes().ConvertTypeForMem(D->getType());
@@ -1091,16 +1099,16 @@ void CodeGenModule::EmitAliasDefinition(const ValueDecl *D) {
// Set attributes which are particular to an alias; this is a
// specialization of the attributes which may be set on a global
// variable/function.
- if (D->hasAttr<DLLExportAttr>(getContext())) {
+ if (D->hasAttr<DLLExportAttr>()) {
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
// The dllexport attribute is ignored for undefined symbols.
- if (FD->getBody(getContext()))
+ if (FD->getBody())
GA->setLinkage(llvm::Function::DLLExportLinkage);
} else {
GA->setLinkage(llvm::Function::DLLExportLinkage);
}
- } else if (D->hasAttr<WeakAttr>(getContext()) ||
- D->hasAttr<WeakImportAttr>(getContext())) {
+ } else if (D->hasAttr<WeakAttr>() ||
+ D->hasAttr<WeakImportAttr>()) {
GA->setLinkage(llvm::Function::WeakAnyLinkage);
}
@@ -1254,7 +1262,7 @@ GetAddrOfConstantCFString(const StringLiteral *Literal) {
cast<llvm::StructType>(getTypes().ConvertType(CFTy));
std::vector<llvm::Constant*> Fields;
- RecordDecl::field_iterator Field = CFRD->field_begin(getContext());
+ RecordDecl::field_iterator Field = CFRD->field_begin();
// Class pointer.
FieldDecl *CurField = *Field++;
@@ -1424,8 +1432,7 @@ llvm::Constant *CodeGenModule::GetAddrOfConstantCString(const std::string &str,
void CodeGenModule::EmitObjCPropertyImplementations(const
ObjCImplementationDecl *D) {
for (ObjCImplementationDecl::propimpl_iterator
- i = D->propimpl_begin(getContext()),
- e = D->propimpl_end(getContext()); i != e; ++i) {
+ i = D->propimpl_begin(), e = D->propimpl_end(); i != e; ++i) {
ObjCPropertyImplDecl *PID = *i;
// Dynamic is just for type-checking.
@@ -1437,11 +1444,11 @@ void CodeGenModule::EmitObjCPropertyImplementations(const
// we want, that just indicates if the decl came from a
// property. What we want to know is if the method is defined in
// this implementation.
- if (!D->getInstanceMethod(getContext(), PD->getGetterName()))
+ if (!D->getInstanceMethod(PD->getGetterName()))
CodeGenFunction(*this).GenerateObjCGetter(
const_cast<ObjCImplementationDecl *>(D), PID);
if (!PD->isReadOnly() &&
- !D->getInstanceMethod(getContext(), PD->getSetterName()))
+ !D->getInstanceMethod(PD->getSetterName()))
CodeGenFunction(*this).GenerateObjCSetter(
const_cast<ObjCImplementationDecl *>(D), PID);
}
@@ -1450,8 +1457,7 @@ void CodeGenModule::EmitObjCPropertyImplementations(const
/// EmitNamespace - Emit all declarations in a namespace.
void CodeGenModule::EmitNamespace(const NamespaceDecl *ND) {
- for (RecordDecl::decl_iterator I = ND->decls_begin(getContext()),
- E = ND->decls_end(getContext());
+ for (RecordDecl::decl_iterator I = ND->decls_begin(), E = ND->decls_end();
I != E; ++I)
EmitTopLevelDecl(*I);
}
@@ -1463,8 +1469,7 @@ void CodeGenModule::EmitLinkageSpec(const LinkageSpecDecl *LSD) {
return;
}
- for (RecordDecl::decl_iterator I = LSD->decls_begin(getContext()),
- E = LSD->decls_end(getContext());
+ for (RecordDecl::decl_iterator I = LSD->decls_begin(), E = LSD->decls_end();
I != E; ++I)
EmitTopLevelDecl(*I);
}
@@ -1477,9 +1482,19 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
if (Diags.hasErrorOccurred())
return;
+ // Ignore dependent declarations.
+ if (D->getDeclContext() && D->getDeclContext()->isDependentContext())
+ return;
+
switch (D->getKind()) {
case Decl::CXXMethod:
case Decl::Function:
+ // Skip function templates
+ if (cast<FunctionDecl>(D)->getDescribedFunctionTemplate())
+ return;
+
+ // Fall through
+
case Decl::Var:
EmitGlobal(GlobalDecl(cast<ValueDecl>(D)));
break;
@@ -1490,6 +1505,8 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
break;
// No code generation needed.
case Decl::Using:
+ case Decl::ClassTemplate:
+ case Decl::FunctionTemplate:
break;
case Decl::CXXConstructor:
EmitCXXConstructors(cast<CXXConstructorDecl>(D));
@@ -1530,7 +1547,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
case Decl::ObjCMethod: {
ObjCMethodDecl *OMD = cast<ObjCMethodDecl>(D);
// If this is not a prototype, emit the body.
- if (OMD->getBody(getContext()))
+ if (OMD->getBody())
CodeGenFunction(*this).GenerateObjCMethod(OMD);
break;
}
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 4d50e8946bd6..ba9f1b28a07d 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -373,7 +373,8 @@ public:
GVA_Internal,
GVA_C99Inline,
GVA_CXXInline,
- GVA_StrongExternal
+ GVA_StrongExternal,
+ GVA_TemplateInstantiation
};
private:
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index f31c610bf97d..1a30ea37fbbc 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -449,7 +449,7 @@ const llvm::Type *CodeGenTypes::ConvertTagDeclType(const TagDecl *TD) {
const RecordDecl *RD = cast<const RecordDecl>(TD);
// There isn't any extra information for empty structures/unions.
- if (RD->field_empty(getContext())) {
+ if (RD->field_empty()) {
ResultType = llvm::StructType::get(std::vector<const llvm::Type*>());
} else {
// Layout fields.
@@ -532,8 +532,8 @@ void RecordOrganizer::layoutStructFields(const ASTRecordLayout &RL) {
std::vector<const llvm::Type*> LLVMFields;
unsigned curField = 0;
- for (RecordDecl::field_iterator Field = RD.field_begin(CGT.getContext()),
- FieldEnd = RD.field_end(CGT.getContext());
+ for (RecordDecl::field_iterator Field = RD.field_begin(),
+ FieldEnd = RD.field_end();
Field != FieldEnd; ++Field) {
uint64_t offset = RL.getFieldOffset(curField);
const llvm::Type *Ty = CGT.ConvertTypeForMemRecursive(Field->getType());
@@ -578,8 +578,8 @@ void RecordOrganizer::layoutStructFields(const ASTRecordLayout &RL) {
/// all fields are added.
void RecordOrganizer::layoutUnionFields(const ASTRecordLayout &RL) {
unsigned curField = 0;
- for (RecordDecl::field_iterator Field = RD.field_begin(CGT.getContext()),
- FieldEnd = RD.field_end(CGT.getContext());
+ for (RecordDecl::field_iterator Field = RD.field_begin(),
+ FieldEnd = RD.field_end();
Field != FieldEnd; ++Field) {
// The offset should usually be zero, but bitfields could be strange
uint64_t offset = RL.getFieldOffset(curField);
diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp
index b5ad5acc0162..8018b4f45a84 100644
--- a/lib/CodeGen/Mangle.cpp
+++ b/lib/CodeGen/Mangle.cpp
@@ -87,7 +87,7 @@ static bool isInCLinkageSpecification(const Decl *D) {
bool CXXNameMangler::mangleFunctionDecl(const FunctionDecl *FD) {
// Clang's "overloadable" attribute extension to C/C++ implies
// name mangling (always).
- if (!FD->hasAttr<OverloadableAttr>(Context)) {
+ if (!FD->hasAttr<OverloadableAttr>()) {
// C functions are not mangled, and "main" is never mangled.
if (!Context.getLangOptions().CPlusPlus || FD->isMain())
return false;
@@ -111,7 +111,7 @@ bool CXXNameMangler::mangleFunctionDecl(const FunctionDecl *FD) {
bool CXXNameMangler::mangle(const NamedDecl *D) {
// Any decl can be declared with __asm("foo") on it, and this takes
// precedence over all other naming in the .o file.
- if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>(Context)) {
+ if (const AsmLabelAttr *ALA = D->getAttr<AsmLabelAttr>()) {
// If we have an asm name, then we use it as the mangling.
Out << '\01'; // LLVM IR Marker for __asm("foo")
Out << ALA->getLabel();
@@ -170,7 +170,29 @@ void CXXNameMangler::mangleGuardVariable(const VarDecl *D)
void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) {
// <encoding> ::= <function name> <bare-function-type>
mangleName(FD);
- mangleBareFunctionType(FD->getType()->getAsFunctionType(), false);
+
+ // Whether the mangling of a function type includes the return type depends
+ // on the context and the nature of the function. The rules for deciding
+ // whether the return type is included are:
+ //
+ // 1. Template functions (names or types) have return types encoded, with
+ // the exceptions listed below.
+ // 2. Function types not appearing as part of a function name mangling,
+ // e.g. parameters, pointer types, etc., have return type encoded, with the
+ // exceptions listed below.
+ // 3. Non-template function names do not have return types encoded.
+ //
+ // The exceptions mentioned in (1) and (2) above, for which the return
+ // type is never included, are
+ // 1. Constructors.
+ // 2. Destructors.
+ // 3. Conversion operator functions, e.g. operator int.
+ bool MangleReturnType = false;
+ if (FD->getPrimaryTemplate() &&
+ !(isa<CXXConstructorDecl>(FD) || isa<CXXDestructorDecl>(FD) ||
+ isa<CXXConversionDecl>(FD)))
+ MangleReturnType = true;
+ mangleBareFunctionType(FD->getType()->getAsFunctionType(), MangleReturnType);
}
static bool isStdNamespace(const DeclContext *DC) {
@@ -253,6 +275,12 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND) {
assert(false && "Can't mangle a using directive name!");
break;
}
+
+ if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
+ if (const TemplateArgumentList *TemplateArgs
+ = Function->getTemplateSpecializationArgs())
+ mangleTemplateArgumentList(*TemplateArgs);
+ }
}
void CXXNameMangler::mangleSourceName(const IdentifierInfo *II) {
diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp
index 9b85df61da05..4835454b47df 100644
--- a/lib/CodeGen/ModuleBuilder.cpp
+++ b/lib/CodeGen/ModuleBuilder.cpp
@@ -19,6 +19,7 @@
#include "clang/AST/Expr.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/TargetInfo.h"
+#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Support/Compiler.h"
@@ -37,8 +38,8 @@ namespace {
llvm::OwningPtr<CodeGen::CodeGenModule> Builder;
public:
CodeGeneratorImpl(Diagnostic &diags, const std::string& ModuleName,
- const CompileOptions &CO)
- : Diags(diags), CompileOpts(CO), M(new llvm::Module(ModuleName)) {}
+ const CompileOptions &CO, llvm::LLVMContext& C)
+ : Diags(diags), CompileOpts(CO), M(new llvm::Module(ModuleName, C)) {}
virtual ~CodeGeneratorImpl() {}
@@ -95,6 +96,7 @@ namespace {
CodeGenerator *clang::CreateLLVMCodeGen(Diagnostic &Diags,
const std::string& ModuleName,
- const CompileOptions &CO) {
- return new CodeGeneratorImpl(Diags, ModuleName, CO);
+ const CompileOptions &CO,
+ llvm::LLVMContext& C) {
+ return new CodeGeneratorImpl(Diags, ModuleName, CO, C);
}
diff --git a/lib/CodeGen/TargetABIInfo.cpp b/lib/CodeGen/TargetABIInfo.cpp
index 361e5c0005cc..896dbd685037 100644
--- a/lib/CodeGen/TargetABIInfo.cpp
+++ b/lib/CodeGen/TargetABIInfo.cpp
@@ -74,8 +74,8 @@ static bool isEmptyRecord(ASTContext &Context, QualType T) {
const RecordDecl *RD = RT->getDecl();
if (RD->hasFlexibleArrayMember())
return false;
- for (RecordDecl::field_iterator i = RD->field_begin(Context),
- e = RD->field_end(Context); i != e; ++i)
+ for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
+ i != e; ++i)
if (!isEmptyField(Context, *i))
return false;
return true;
@@ -99,8 +99,8 @@ static const Type *isSingleElementStruct(QualType T, ASTContext &Context) {
return 0;
const Type *Found = 0;
- for (RecordDecl::field_iterator i = RD->field_begin(Context),
- e = RD->field_end(Context); i != e; ++i) {
+ for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
+ i != e; ++i) {
const FieldDecl *FD = *i;
QualType FT = FD->getType();
@@ -142,8 +142,8 @@ static bool is32Or64BitBasicType(QualType Ty, ASTContext &Context) {
static bool areAllFields32Or64BitBasicType(const RecordDecl *RD,
ASTContext &Context) {
- for (RecordDecl::field_iterator i = RD->field_begin(Context),
- e = RD->field_end(Context); i != e; ++i) {
+ for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
+ i != e; ++i) {
const FieldDecl *FD = *i;
if (!is32Or64BitBasicType(FD->getType(), Context))
@@ -160,8 +160,8 @@ static bool areAllFields32Or64BitBasicType(const RecordDecl *RD,
}
static bool typeContainsSSEVector(const RecordDecl *RD, ASTContext &Context) {
- for (RecordDecl::field_iterator i = RD->field_begin(Context),
- e = RD->field_end(Context); i != e; ++i) {
+ for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
+ i != e; ++i) {
const FieldDecl *FD = *i;
if (FD->getType()->isVectorType() &&
@@ -269,8 +269,8 @@ bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty,
// Structure types are passed in register if all fields would be
// passed in a register.
- for (RecordDecl::field_iterator i = RT->getDecl()->field_begin(Context),
- e = RT->getDecl()->field_end(Context); i != e; ++i) {
+ for (RecordDecl::field_iterator i = RT->getDecl()->field_begin(),
+ e = RT->getDecl()->field_end(); i != e; ++i) {
const FieldDecl *FD = *i;
// Empty fields are ignored.
@@ -707,8 +707,8 @@ void X86_64ABIInfo::classify(QualType Ty,
// Reset Lo class, this will be recomputed.
Current = NoClass;
unsigned idx = 0;
- for (RecordDecl::field_iterator i = RD->field_begin(Context),
- e = RD->field_end(Context); i != e; ++i, ++idx) {
+ for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
+ i != e; ++i, ++idx) {
uint64_t Offset = OffsetBase + Layout.getFieldOffset(idx);
bool BitField = i->isBitField();
diff --git a/lib/Driver/ArgList.cpp b/lib/Driver/ArgList.cpp
index 593694cfbbf6..54dd4bb77538 100644
--- a/lib/Driver/ArgList.cpp
+++ b/lib/Driver/ArgList.cpp
@@ -49,6 +49,35 @@ Arg *ArgList::getLastArg(options::ID Id0, options::ID Id1, bool Claim) const {
return Res;
}
+Arg *ArgList::getLastArg(options::ID Id0, options::ID Id1, options::ID Id2,
+ bool Claim) const {
+ Arg *Res = 0;
+ Arg *A0 = getLastArg(Id0, false);
+ Arg *A1 = getLastArg(Id1, false);
+ Arg *A2 = getLastArg(Id2, false);
+
+ int A0Idx = A0 ? A0->getIndex() : -1;
+ int A1Idx = A1 ? A1->getIndex() : -1;
+ int A2Idx = A2 ? A2->getIndex() : -1;
+
+ if (A0Idx > A1Idx) {
+ if (A0Idx > A2Idx)
+ Res = A0;
+ else if (A2Idx != -1)
+ Res = A2;
+ } else {
+ if (A1Idx > A2Idx)
+ Res = A1;
+ else if (A2Idx != -1)
+ Res = A2;
+ }
+
+ if (Claim && Res)
+ Res->claim();
+
+ return Res;
+}
+
bool ArgList::hasFlag(options::ID Pos, options::ID Neg, bool Default) const {
if (Arg *A = getLastArg(Pos, Neg))
return A->getOption().matches(Pos);
diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp
index 1e044c6b8fdc..7e29b67769d3 100644
--- a/lib/Driver/Compilation.cpp
+++ b/lib/Driver/Compilation.cpp
@@ -21,8 +21,8 @@
#include <errno.h>
using namespace clang::driver;
-Compilation::Compilation(Driver &D,
- ToolChain &_DefaultToolChain,
+Compilation::Compilation(const Driver &D,
+ const ToolChain &_DefaultToolChain,
InputArgList *_Args)
: TheDriver(D), DefaultToolChain(_DefaultToolChain), Args(_Args) {
}
@@ -105,7 +105,8 @@ bool Compilation::CleanupFileList(const ArgStringList &Files,
return Success;
}
-int Compilation::ExecuteCommand(const Command &C) const {
+int Compilation::ExecuteCommand(const Command &C,
+ const Command *&FailingCommand) const {
llvm::sys::Path Prog(C.getExecutable());
const char **Argv = new const char*[C.getArguments().size() + 2];
Argv[0] = C.getExecutable();
@@ -126,49 +127,31 @@ int Compilation::ExecuteCommand(const Command &C) const {
getDriver().Diag(clang::diag::err_drv_command_failure) << Error;
}
+ if (Res)
+ FailingCommand = &C;
+
delete[] Argv;
return Res;
}
-int Compilation::ExecuteJob(const Job &J) const {
+int Compilation::ExecuteJob(const Job &J,
+ const Command *&FailingCommand) const {
if (const Command *C = dyn_cast<Command>(&J)) {
- return ExecuteCommand(*C);
+ return ExecuteCommand(*C, FailingCommand);
} else if (const PipedJob *PJ = dyn_cast<PipedJob>(&J)) {
// Piped commands with a single job are easy.
if (PJ->size() == 1)
- return ExecuteCommand(**PJ->begin());
+ return ExecuteCommand(**PJ->begin(), FailingCommand);
+ FailingCommand = *PJ->begin();
getDriver().Diag(clang::diag::err_drv_unsupported_opt) << "-pipe";
return 1;
} else {
const JobList *Jobs = cast<JobList>(&J);
for (JobList::const_iterator
it = Jobs->begin(), ie = Jobs->end(); it != ie; ++it)
- if (int Res = ExecuteJob(**it))
+ if (int Res = ExecuteJob(**it, FailingCommand))
return Res;
return 0;
}
}
-
-int Compilation::Execute() const {
- // Just print if -### was present.
- if (getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
- PrintJob(llvm::errs(), Jobs, "\n", true);
- return 0;
- }
-
- // If there were errors building the compilation, quit now.
- if (getDriver().getDiags().getNumErrors())
- return 1;
-
- int Res = ExecuteJob(Jobs);
-
- // Remove temp files.
- CleanupFileList(TempFiles);
-
- // If the compilation failed, remove result files as well.
- if (Res != 0 && !getArgs().hasArg(options::OPT_save_temps))
- CleanupFileList(ResultFiles, true);
-
- return Res;
-}
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 8c2676b8cd7d..1b0b5615dfbc 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -217,6 +217,54 @@ Compilation *Driver::BuildCompilation(int argc, const char **argv) {
return C;
}
+int Driver::ExecuteCompilation(const Compilation &C) const {
+ // Just print if -### was present.
+ if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) {
+ C.PrintJob(llvm::errs(), C.getJobs(), "\n", true);
+ return 0;
+ }
+
+ // If there were errors building the compilation, quit now.
+ if (getDiags().getNumErrors())
+ return 1;
+
+ const Command *FailingCommand = 0;
+ int Res = C.ExecuteJob(C.getJobs(), FailingCommand);
+
+ // Remove temp files.
+ C.CleanupFileList(C.getTempFiles());
+
+ // If the compilation failed, remove result files as well.
+ if (Res != 0 && !C.getArgs().hasArg(options::OPT_save_temps))
+ C.CleanupFileList(C.getResultFiles(), true);
+
+ // Print extra information about abnormal failures, if possible.
+ if (Res) {
+ // This is ad-hoc, but we don't want to be excessively noisy. If the result
+ // status was 1, assume the command failed normally. In particular, if it
+ // was the compiler then assume it gave a reasonable error code. Failures in
+ // other tools are less common, and they generally have worse diagnostics,
+ // so always print the diagnostic there.
+ const Action &Source = FailingCommand->getSource();
+ bool IsFriendlyTool = (isa<PreprocessJobAction>(Source) ||
+ isa<PrecompileJobAction>(Source) ||
+ isa<AnalyzeJobAction>(Source) ||
+ isa<CompileJobAction>(Source));
+
+ if (!IsFriendlyTool || Res != 1) {
+ // FIXME: See FIXME above regarding result code interpretation.
+ if (Res < 0)
+ Diag(clang::diag::err_drv_command_signalled)
+ << Source.getClassName() << -Res;
+ else
+ Diag(clang::diag::err_drv_command_failed)
+ << Source.getClassName() << Res;
+ }
+ }
+
+ return Res;
+}
+
void Driver::PrintOptions(const ArgList &Args) const {
unsigned i = 0;
for (ArgList::const_iterator it = Args.begin(), ie = Args.end();
@@ -1205,6 +1253,8 @@ const HostInfo *Driver::GetHostInfo(const char *TripleStr) const {
return createDarwinHostInfo(*this, Triple);
case llvm::Triple::DragonFly:
return createDragonFlyHostInfo(*this, Triple);
+ case llvm::Triple::OpenBSD:
+ return createOpenBSDHostInfo(*this, Triple);
case llvm::Triple::FreeBSD:
return createFreeBSDHostInfo(*this, Triple);
case llvm::Triple::Linux:
diff --git a/lib/Driver/HostInfo.cpp b/lib/Driver/HostInfo.cpp
index 831e11b98e42..602a97713505 100644
--- a/lib/Driver/HostInfo.cpp
+++ b/lib/Driver/HostInfo.cpp
@@ -234,6 +234,57 @@ ToolChain *UnknownHostInfo::getToolChain(const ArgList &Args,
return TC;
}
+// OpenBSD Host Info
+
+/// OpenBSDHostInfo - OpenBSD host information implementation.
+class OpenBSDHostInfo : public HostInfo {
+ /// Cache of tool chains we have created.
+ mutable llvm::StringMap<ToolChain*> ToolChains;
+
+public:
+ OpenBSDHostInfo(const Driver &D, const llvm::Triple& Triple)
+ : HostInfo(D, Triple) {}
+ ~OpenBSDHostInfo();
+
+ virtual bool useDriverDriver() const;
+
+ virtual types::ID lookupTypeForExtension(const char *Ext) const {
+ return types::lookupTypeForExtension(Ext);
+ }
+
+ virtual ToolChain *getToolChain(const ArgList &Args,
+ const char *ArchName) const;
+};
+
+OpenBSDHostInfo::~OpenBSDHostInfo() {
+ for (llvm::StringMap<ToolChain*>::iterator
+ it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
+ delete it->second;
+}
+
+bool OpenBSDHostInfo::useDriverDriver() const {
+ return false;
+}
+
+ToolChain *OpenBSDHostInfo::getToolChain(const ArgList &Args,
+ const char *ArchName) const {
+ assert(!ArchName &&
+ "Unexpected arch name on platform without driver driver support.");
+
+ std::string Arch = getArchName();
+ ArchName = Arch.c_str();
+
+ ToolChain *&TC = ToolChains[ArchName];
+ if (!TC) {
+ llvm::Triple TCTriple(getTriple());
+ TCTriple.setArchName(ArchName);
+
+ TC = new toolchains::OpenBSD(*this, TCTriple);
+ }
+
+ return TC;
+}
+
// FreeBSD Host Info
/// FreeBSDHostInfo - FreeBSD host information implementation.
@@ -417,6 +468,12 @@ clang::driver::createDarwinHostInfo(const Driver &D,
}
const HostInfo *
+clang::driver::createOpenBSDHostInfo(const Driver &D,
+ const llvm::Triple& Triple) {
+ return new OpenBSDHostInfo(D, Triple);
+}
+
+const HostInfo *
clang::driver::createFreeBSDHostInfo(const Driver &D,
const llvm::Triple& Triple) {
return new FreeBSDHostInfo(D, Triple);
diff --git a/lib/Driver/Job.cpp b/lib/Driver/Job.cpp
index 222cf15db60f..1b0ea18453d0 100644
--- a/lib/Driver/Job.cpp
+++ b/lib/Driver/Job.cpp
@@ -14,8 +14,10 @@ using namespace clang::driver;
Job::~Job() {}
-Command::Command(const char *_Executable, const ArgStringList &_Arguments)
- : Job(CommandClass), Executable(_Executable), Arguments(_Arguments) {
+Command::Command(const Action &_Source, const char *_Executable,
+ const ArgStringList &_Arguments)
+ : Job(CommandClass), Source(_Source), Executable(_Executable),
+ Arguments(_Arguments) {
}
PipedJob::PipedJob() : Job(PipedJobClass) {}
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 436d343dd021..f663ed49536e 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -384,6 +384,36 @@ DerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args) const {
return new DerivedArgList(Args, true);
}
+/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
+
+OpenBSD::OpenBSD(const HostInfo &Host, const llvm::Triple& Triple)
+ : Generic_GCC(Host, Triple) {
+ getFilePaths().push_back(getHost().getDriver().Dir + "/../lib");
+ getFilePaths().push_back("/usr/lib");
+}
+
+Tool &OpenBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
+ Action::ActionClass Key;
+ if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
+ Key = Action::AnalyzeJobClass;
+ else
+ Key = JA.getKind();
+
+ Tool *&T = Tools[Key];
+ if (!T) {
+ switch (Key) {
+ case Action::AssembleJobClass:
+ T = new tools::openbsd::Assemble(*this); break;
+ case Action::LinkJobClass:
+ T = new tools::openbsd::Link(*this); break;
+ default:
+ T = &Generic_GCC::SelectTool(C, JA);
+ }
+ }
+
+ return *T;
+}
+
/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
FreeBSD::FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32)
diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h
index 3ecd1715da96..c921d52864f0 100644
--- a/lib/Driver/ToolChains.h
+++ b/lib/Driver/ToolChains.h
@@ -107,6 +107,13 @@ public:
virtual const char *GetDefaultRelocationModel() const { return "pic"; }
};
+class VISIBILITY_HIDDEN OpenBSD : public Generic_GCC {
+public:
+ OpenBSD(const HostInfo &Host, const llvm::Triple& Triple);
+
+ virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
+};
+
class VISIBILITY_HIDDEN FreeBSD : public Generic_GCC {
public:
FreeBSD(const HostInfo &Host, const llvm::Triple& Triple, bool Lib32);
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index bfc247a015ff..d198a54cf7dd 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -498,6 +498,18 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_fvisibility_EQ);
Args.AddLastArg(CmdArgs, options::OPT_fwritable_strings);
+ // Forward stack protector flags.
+ if (Arg *A = Args.getLastArg(options::OPT_fno_stack_protector,
+ options::OPT_fstack_protector_all,
+ options::OPT_fstack_protector)) {
+ if (A->getOption().matches(options::OPT_fno_stack_protector))
+ CmdArgs.push_back("--stack-protector=0");
+ else if (A->getOption().matches(options::OPT_fstack_protector))
+ CmdArgs.push_back("--stack-protector=1");
+ else
+ CmdArgs.push_back("--stack-protector=2");
+ }
+
// Forward -f options with positive and negative forms; we translate
// these by hand.
@@ -616,7 +628,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "clang-cc").c_str());
- Dest.addCommand(new Command(Exec, CmdArgs));
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
// Explicitly warn that these options are unsupported, even though
// we are allowing compilation to continue.
@@ -747,7 +759,7 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
getToolChain().getHost().getDriver().CCCGenericGCCName.c_str();
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, GCCName).c_str());
- Dest.addCommand(new Command(Exec, CmdArgs));
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
void gcc::Preprocess::RenderExtraToolArgs(ArgStringList &CmdArgs) const {
@@ -1123,7 +1135,7 @@ void darwin::Preprocess::ConstructJob(Compilation &C, const JobAction &JA,
const char *CC1Name = getCC1Name(Inputs[0].getType());
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, CC1Name).c_str());
- Dest.addCommand(new Command(Exec, CmdArgs));
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
void darwin::Compile::ConstructJob(Compilation &C, const JobAction &JA,
@@ -1211,7 +1223,7 @@ void darwin::Compile::ConstructJob(Compilation &C, const JobAction &JA,
const char *CC1Name = getCC1Name(Inputs[0].getType());
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, CC1Name).c_str());
- Dest.addCommand(new Command(Exec, CmdArgs));
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
@@ -1264,7 +1276,7 @@ void darwin::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "as").c_str());
- Dest.addCommand(new Command(Exec, CmdArgs));
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
/// Helper routine for seeing if we should use dsymutil; this is a
@@ -1688,7 +1700,7 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "ld").c_str());
- Dest.addCommand(new Command(Exec, CmdArgs));
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
// Find the first non-empty base input (we want to ignore linker
// inputs).
@@ -1718,7 +1730,7 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA,
Args.MakeArgString(getToolChain().GetProgramPath(C, "dsymutil").c_str());
ArgStringList CmdArgs;
CmdArgs.push_back(Output.getFilename());
- C.getJobs().addCommand(new Command(Exec, CmdArgs));
+ C.getJobs().addCommand(new Command(JA, Exec, CmdArgs));
}
}
}
@@ -1744,9 +1756,121 @@ void darwin::Lipo::ConstructJob(Compilation &C, const JobAction &JA,
}
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "lipo").c_str());
- Dest.addCommand(new Command(Exec, CmdArgs));
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
+}
+
+void openbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
+ Job &Dest, const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &Args,
+ const char *LinkingOutput) const
+{
+ ArgStringList CmdArgs;
+
+ Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
+ options::OPT_Xassembler);
+
+ CmdArgs.push_back("-o");
+ if (Output.isPipe())
+ CmdArgs.push_back("-");
+ else
+ CmdArgs.push_back(Output.getFilename());
+
+ for (InputInfoList::const_iterator
+ it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+ const InputInfo &II = *it;
+ if (II.isPipe())
+ CmdArgs.push_back("-");
+ else
+ CmdArgs.push_back(II.getFilename());
+ }
+
+ const char *Exec =
+ Args.MakeArgString(getToolChain().GetProgramPath(C, "as").c_str());
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
+void openbsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
+ Job &Dest, const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &Args,
+ const char *LinkingOutput) const {
+ const Driver &D = getToolChain().getHost().getDriver();
+ ArgStringList CmdArgs;
+
+ if (Args.hasArg(options::OPT_static)) {
+ CmdArgs.push_back("-Bstatic");
+ } else {
+ CmdArgs.push_back("--eh-frame-hdr");
+ if (Args.hasArg(options::OPT_shared)) {
+ CmdArgs.push_back("-Bshareable");
+ } else {
+ CmdArgs.push_back("-dynamic-linker");
+ CmdArgs.push_back("/usr/libexec/ld.so");
+ }
+ }
+
+ if (Output.isPipe()) {
+ CmdArgs.push_back("-o");
+ CmdArgs.push_back("-");
+ } else if (Output.isFilename()) {
+ CmdArgs.push_back("-o");
+ CmdArgs.push_back(Output.getFilename());
+ } else {
+ assert(Output.isNothing() && "Invalid output.");
+ }
+
+ if (!Args.hasArg(options::OPT_nostdlib) &&
+ !Args.hasArg(options::OPT_nostartfiles)) {
+ if (!Args.hasArg(options::OPT_shared)) {
+ CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crt0.o").c_str()));
+ CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbegin.o").c_str()));
+ } else {
+ CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtbeginS.o").c_str()));
+ }
+ }
+
+ Args.AddAllArgs(CmdArgs, options::OPT_L);
+ Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
+ Args.AddAllArgs(CmdArgs, options::OPT_e);
+
+ for (InputInfoList::const_iterator
+ it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
+ const InputInfo &II = *it;
+
+ // Don't try to pass LLVM inputs to a generic gcc.
+ if (II.getType() == types::TY_LLVMBC)
+ D.Diag(clang::diag::err_drv_no_linker_llvm_support)
+ << getToolChain().getTripleString().c_str();
+
+ if (II.isPipe())
+ CmdArgs.push_back("-");
+ else if (II.isFilename())
+ CmdArgs.push_back(II.getFilename());
+ else
+ II.getInputArg().renderAsInput(Args, CmdArgs);
+ }
+
+ if (!Args.hasArg(options::OPT_nostdlib) &&
+ !Args.hasArg(options::OPT_nodefaultlibs)) {
+
+ if (Args.hasArg(options::OPT_pthread))
+ CmdArgs.push_back("-pthread");
+ CmdArgs.push_back("-lc");
+ }
+
+ if (!Args.hasArg(options::OPT_nostdlib) &&
+ !Args.hasArg(options::OPT_nostartfiles)) {
+ if (!Args.hasArg(options::OPT_shared))
+ CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtend.o").c_str()));
+ else
+ CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o").c_str()));
+ }
+
+ const char *Exec =
+ Args.MakeArgString(getToolChain().GetProgramPath(C, "ld").c_str());
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
+}
void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
Job &Dest, const InputInfo &Output,
@@ -1781,7 +1905,7 @@ void freebsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "as").c_str());
- Dest.addCommand(new Command(Exec, CmdArgs));
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
@@ -1892,7 +2016,7 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "ld").c_str());
- Dest.addCommand(new Command(Exec, CmdArgs));
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
/// DragonFly Tools
@@ -1931,7 +2055,7 @@ void dragonfly::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "as").c_str());
- Dest.addCommand(new Command(Exec, CmdArgs));
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA,
@@ -2055,5 +2179,5 @@ void dragonfly::Link::ConstructJob(Compilation &C, const JobAction &JA,
const char *Exec =
Args.MakeArgString(getToolChain().GetProgramPath(C, "ld").c_str());
- Dest.addCommand(new Command(Exec, CmdArgs));
+ Dest.addCommand(new Command(JA, Exec, CmdArgs));
}
diff --git a/lib/Driver/Tools.h b/lib/Driver/Tools.h
index db108db2b4d7..ab7349600907 100644
--- a/lib/Driver/Tools.h
+++ b/lib/Driver/Tools.h
@@ -241,6 +241,40 @@ namespace darwin {
};
}
+ /// openbsd -- Directly call GNU Binutils assembler and linker
+namespace openbsd {
+ class VISIBILITY_HIDDEN Assemble : public Tool {
+ public:
+ Assemble(const ToolChain &TC) : Tool("openbsd::Assemble", TC) {}
+
+ virtual bool acceptsPipedInput() const { return true; }
+ virtual bool canPipeOutput() const { return true; }
+ virtual bool hasIntegratedCPP() const { return false; }
+
+ virtual void ConstructJob(Compilation &C, const JobAction &JA,
+ Job &Dest,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &TCArgs,
+ const char *LinkingOutput) const;
+ };
+ class VISIBILITY_HIDDEN Link : public Tool {
+ public:
+ Link(const ToolChain &TC) : Tool("openbsd::Link", TC) {}
+
+ virtual bool acceptsPipedInput() const { return true; }
+ virtual bool canPipeOutput() const { return true; }
+ virtual bool hasIntegratedCPP() const { return false; }
+
+ virtual void ConstructJob(Compilation &C, const JobAction &JA,
+ Job &Dest,
+ const InputInfo &Output,
+ const InputInfoList &Inputs,
+ const ArgList &TCArgs,
+ const char *LinkingOutput) const;
+ };
+}
+
/// freebsd -- Directly call GNU Binutils assembler and linker
namespace freebsd {
class VISIBILITY_HIDDEN Assemble : public Tool {
diff --git a/lib/Frontend/ASTConsumers.cpp b/lib/Frontend/ASTConsumers.cpp
index 5844be826cf7..8f0ad13319eb 100644
--- a/lib/Frontend/ASTConsumers.cpp
+++ b/lib/Frontend/ASTConsumers.cpp
@@ -44,7 +44,7 @@ namespace {
virtual void HandleTranslationUnit(ASTContext &Context) {
PrintingPolicy Policy = Context.PrintingPolicy;
Policy.Dump = Dump;
- Context.getTranslationUnitDecl()->print(Out, Context, Policy);
+ Context.getTranslationUnitDecl()->print(Out, Policy);
}
};
} // end anonymous namespace
@@ -70,8 +70,8 @@ namespace {
virtual void HandleTranslationUnit(ASTContext &Ctx) {
Doc.addSubNode("TranslationUnit");
for (DeclContext::decl_iterator
- D = Ctx.getTranslationUnitDecl()->decls_begin(Ctx),
- DEnd = Ctx.getTranslationUnitDecl()->decls_end(Ctx);
+ D = Ctx.getTranslationUnitDecl()->decls_begin(),
+ DEnd = Ctx.getTranslationUnitDecl()->decls_end();
D != DEnd;
++D)
{
@@ -114,7 +114,7 @@ namespace {
void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- FD->print(llvm::errs(), *Context);
+ FD->print(llvm::errs());
if (FD->getBodyIfAvailable()) {
llvm::cerr << '\n';
@@ -125,7 +125,7 @@ void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
}
if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
- MD->print(llvm::errs(), *Context);
+ MD->print(llvm::errs());
if (MD->getBody()) {
llvm::cerr << '\n';
@@ -340,10 +340,7 @@ void DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
Out << "\n";
// Print decls in the DeclContext.
- // FIXME: Should not use a NULL DeclContext!
- ASTContext *Context = 0;
- for (DeclContext::decl_iterator I = DC->decls_begin(*Context),
- E = DC->decls_end(*Context);
+ for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
I != E; ++I) {
for (unsigned i = 0; i < Indentation; ++i)
Out << " ";
diff --git a/lib/Frontend/AnalysisConsumer.cpp b/lib/Frontend/AnalysisConsumer.cpp
index d8fa141d8cb6..06af2d9a4e58 100644
--- a/lib/Frontend/AnalysisConsumer.cpp
+++ b/lib/Frontend/AnalysisConsumer.cpp
@@ -307,7 +307,7 @@ void AnalysisConsumer::HandleTopLevelSingleDecl(Decl *D) {
Opts.AnalyzeSpecificFunction != FD->getIdentifier()->getName())
break;
- Stmt* Body = FD->getBody(*Ctx);
+ Stmt* Body = FD->getBody();
if (Body) HandleCode(FD, Body, FunctionActions);
break;
}
@@ -341,8 +341,8 @@ void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
if (!ObjCImplementationActions.empty()) {
TranslationUnitDecl *TUD = C.getTranslationUnitDecl();
- for (DeclContext::decl_iterator I = TUD->decls_begin(C),
- E = TUD->decls_end(C);
+ for (DeclContext::decl_iterator I = TUD->decls_begin(),
+ E = TUD->decls_end();
I != E; ++I)
if (ObjCImplementationDecl* ID = dyn_cast<ObjCImplementationDecl>(*I))
HandleCode(ID, 0, ObjCImplementationActions);
@@ -479,14 +479,16 @@ static void ActionDisplayLiveVariables(AnalysisManager& mgr) {
static void ActionCFGDump(AnalysisManager& mgr) {
if (CFG* c = mgr.getCFG()) {
mgr.DisplayFunction();
- c->dump();
+ LangOptions LO; // FIXME!
+ c->dump(LO);
}
}
static void ActionCFGView(AnalysisManager& mgr) {
if (CFG* c = mgr.getCFG()) {
mgr.DisplayFunction();
- c->viewCFG();
+ LangOptions LO; // FIXME!
+ c->viewCFG(LO);
}
}
diff --git a/lib/Frontend/Backend.cpp b/lib/Frontend/Backend.cpp
index d8f8625d6740..1c536b07cee2 100644
--- a/lib/Frontend/Backend.cpp
+++ b/lib/Frontend/Backend.cpp
@@ -75,13 +75,14 @@ namespace {
public:
BackendConsumer(BackendAction action, Diagnostic &Diags,
const LangOptions &langopts, const CompileOptions &compopts,
- const std::string &infile, llvm::raw_ostream* OS) :
+ const std::string &infile, llvm::raw_ostream* OS,
+ LLVMContext& C) :
Action(action),
CompileOpts(compopts),
AsmOutStream(OS),
LLVMIRGeneration("LLVM IR Generation Time"),
CodeGenerationTime("Code Generation Time"),
- Gen(CreateLLVMCodeGen(Diags, infile, compopts)),
+ Gen(CreateLLVMCodeGen(Diags, infile, compopts, C)),
TheModule(0), TheTargetData(0), ModuleProvider(0),
CodeGenPasses(0), PerModulePasses(0), PerFunctionPasses(0) {
@@ -359,6 +360,8 @@ ASTConsumer *clang::CreateBackendConsumer(BackendAction Action,
const LangOptions &LangOpts,
const CompileOptions &CompileOpts,
const std::string& InFile,
- llvm::raw_ostream* OS) {
- return new BackendConsumer(Action, Diags, LangOpts, CompileOpts, InFile, OS);
+ llvm::raw_ostream* OS,
+ LLVMContext& C) {
+ return new BackendConsumer(Action, Diags, LangOpts, CompileOpts,
+ InFile, OS, C);
}
diff --git a/lib/Frontend/DeclXML.cpp b/lib/Frontend/DeclXML.cpp
index 5c21999bfa05..68f931fb6c69 100644
--- a/lib/Frontend/DeclXML.cpp
+++ b/lib/Frontend/DeclXML.cpp
@@ -34,8 +34,8 @@ class DocumentXML::DeclPrinter : public DeclVisitor<DocumentXML::DeclPrinter>
void addSubNodes(RecordDecl* RD)
{
- for (RecordDecl::field_iterator i = RD->field_begin(*Doc.Ctx), e = RD->field_end(*Doc.Ctx); i != e; ++i)
- {
+ for (RecordDecl::field_iterator i = RD->field_begin(),
+ e = RD->field_end(); i != e; ++i) {
Visit(*i);
Doc.toParent();
}
@@ -43,8 +43,8 @@ class DocumentXML::DeclPrinter : public DeclVisitor<DocumentXML::DeclPrinter>
void addSubNodes(EnumDecl* ED)
{
- for (EnumDecl::enumerator_iterator i = ED->enumerator_begin(*Doc.Ctx), e = ED->enumerator_end(*Doc.Ctx); i != e; ++i)
- {
+ for (EnumDecl::enumerator_iterator i = ED->enumerator_begin(),
+ e = ED->enumerator_end(); i != e; ++i) {
Visit(*i);
Doc.toParent();
}
@@ -147,7 +147,7 @@ void DocumentXML::writeDeclToXML(Decl *D)
DeclPrinter(*this).Visit(D);
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
{
- if (Stmt *Body = FD->getBody(*Ctx)) {
+ if (Stmt *Body = FD->getBody()) {
addSubNode("Body");
PrintStmt(Body);
toParent();
diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp
index 7a2b3a7317b4..8c80786210ff 100644
--- a/lib/Frontend/InitHeaderSearch.cpp
+++ b/lib/Frontend/InitHeaderSearch.cpp
@@ -178,6 +178,14 @@ void InitHeaderSearch::AddDefaultSystemIncludePaths(const LangOptions &Lang) {
AddPath("/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/include/g++-v4/backward",
System, true, false, false);
+ // Gentoo amd64 stable
+ AddPath("/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/include/g++-v4", System,
+ true, false, false);
+ AddPath("/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/include/g++-v4/"
+ "i686-pc-linux-gnu", System, true, false, false);
+ AddPath("/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/include/g++-v4/backward",
+ System, true, false, false);
+
// DragonFly
AddPath("/usr/include/c++/4.1", System, true, false, false);
diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
index 730414e44822..e41dfdda07e9 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -383,7 +383,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
// 16-bit targets doesn't necessarily have a 64-bit type.
if (TI.getLongLongWidth() == 64)
- DefineBuiltinMacro(Buf, "__INT64_TYPE__=long long");
+ DefineType("__INT64_TYPE__", TI.getInt64Type(), Buf);
// Add __builtin_va_list typedef.
{
@@ -423,7 +423,12 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
sprintf(MacroBuf, "__DECIMAL_DIG__=%d",
PickFP(&TI.getLongDoubleFormat(), -1/*FIXME*/, 17, 21, 33, 36));
DefineBuiltinMacro(Buf, MacroBuf);
-
+
+ if (LangOpts.getStackProtectorMode() == LangOptions::SSPOn)
+ DefineBuiltinMacro(Buf, "__SSP__=1");
+ else if (LangOpts.getStackProtectorMode() == LangOptions::SSPReq)
+ DefineBuiltinMacro(Buf, "__SSP_ALL__=2");
+
// Get other target #defines.
TI.getTargetDefines(LangOpts, Buf);
}
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index 765655b01dd0..95b166159e7d 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -344,7 +344,8 @@ PCHReader::PCHReader(Preprocessor &PP, ASTContext *Context)
IdentifierOffsets(0),
MethodPoolLookupTable(0), MethodPoolLookupTableData(0),
TotalSelectorsInMethodPool(0), SelectorOffsets(0),
- TotalNumSelectors(0), NumStatHits(0), NumStatMisses(0),
+ TotalNumSelectors(0), Comments(0), NumComments(0),
+ NumStatHits(0), NumStatMisses(0),
NumSLocEntriesRead(0), NumStatementsRead(0),
NumMacrosRead(0), NumMethodPoolSelectorsRead(0), NumMethodPoolMisses(0),
NumLexicalDeclContextsRead(0), NumVisibleDeclContextsRead(0) { }
@@ -1350,6 +1351,11 @@ PCHReader::ReadPCHBlock() {
case pch::ORIGINAL_FILE_NAME:
OriginalFileName.assign(BlobStart, BlobLen);
break;
+
+ case pch::COMMENT_RANGES:
+ Comments = (SourceRange *)BlobStart;
+ NumComments = BlobLen / sizeof(SourceRange);
+ break;
}
}
Error("premature end of bitstream in PCH file");
@@ -1664,6 +1670,12 @@ bool PCHReader::ParseLanguageOptions(
return false;
}
+void PCHReader::ReadComments(std::vector<SourceRange> &Comments) {
+ Comments.resize(NumComments);
+ std::copy(this->Comments, this->Comments + NumComments,
+ Comments.begin());
+}
+
/// \brief Read and return the type at the given offset.
///
/// This routine actually reads the record corresponding to the type
diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp
index 3f6ae354dc3f..15b54a2d4fc6 100644
--- a/lib/Frontend/PCHReaderDecl.cpp
+++ b/lib/Frontend/PCHReaderDecl.cpp
@@ -80,7 +80,7 @@ void PCHDeclReader::VisitDecl(Decl *D) {
D->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
D->setInvalidDecl(Record[Idx++]);
if (Record[Idx++])
- D->addAttr(*Reader.getContext(), Reader.ReadAttributes());
+ D->addAttr(Reader.ReadAttributes());
D->setImplicit(Record[Idx++]);
D->setUsed(Record[Idx++]);
D->setAccess((AccessSpecifier)Record[Idx++]);
diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp
index d09638806169..eccb53bf8189 100644
--- a/lib/Frontend/PCHReaderStmt.cpp
+++ b/lib/Frontend/PCHReaderStmt.cpp
@@ -1133,6 +1133,5 @@ Stmt *PCHReader::ReadStmt(llvm::BitstreamCursor &Cursor) {
StmtStack.push_back(S);
}
assert(StmtStack.size() == 1 && "Extra expressions on stack!");
- SwitchCaseStmts.clear();
return StmtStack.back();
}
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index e93219e01d5c..3bfc9e89d10a 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -374,7 +374,8 @@ void PCHWriter::WriteBlockInfoBlock() {
RECORD(STAT_CACHE);
RECORD(EXT_VECTOR_DECLS);
RECORD(OBJC_CATEGORY_IMPLEMENTATIONS);
-
+ RECORD(COMMENT_RANGES);
+
// SourceManager Block.
BLOCK(SOURCE_MANAGER_BLOCK);
RECORD(SM_SLOC_FILE_ENTRY);
@@ -989,6 +990,24 @@ void PCHWriter::WritePreprocessor(const Preprocessor &PP) {
Stream.ExitBlock();
}
+void PCHWriter::WriteComments(ASTContext &Context) {
+ using namespace llvm;
+
+ if (Context.Comments.empty())
+ return;
+
+ BitCodeAbbrev *CommentAbbrev = new BitCodeAbbrev();
+ CommentAbbrev->Add(BitCodeAbbrevOp(pch::COMMENT_RANGES));
+ CommentAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
+ unsigned CommentCode = Stream.EmitAbbrev(CommentAbbrev);
+
+ RecordData Record;
+ Record.push_back(pch::COMMENT_RANGES);
+ Stream.EmitRecordWithBlob(CommentCode, Record,
+ (const char*)&Context.Comments[0],
+ Context.Comments.size() * sizeof(SourceRange));
+}
+
//===----------------------------------------------------------------------===//
// Type Serialization
//===----------------------------------------------------------------------===//
@@ -1064,14 +1083,13 @@ void PCHWriter::WriteTypesBlock(ASTContext &Context) {
/// bistream, or 0 if no block was written.
uint64_t PCHWriter::WriteDeclContextLexicalBlock(ASTContext &Context,
DeclContext *DC) {
- if (DC->decls_empty(Context))
+ if (DC->decls_empty())
return 0;
uint64_t Offset = Stream.GetCurrentBitNo();
RecordData Record;
- for (DeclContext::decl_iterator D = DC->decls_begin(Context),
- DEnd = DC->decls_end(Context);
- D != DEnd; ++D)
+ for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end();
+ D != DEnd; ++D)
AddDeclRef(*D, Record);
++NumLexicalDeclContexts;
@@ -1097,7 +1115,7 @@ uint64_t PCHWriter::WriteDeclContextVisibleBlock(ASTContext &Context,
return 0;
// Force the DeclContext to build a its name-lookup table.
- DC->lookup(Context, DeclarationName());
+ DC->lookup(DeclarationName());
// Serialize the contents of the mapping used for lookup. Note that,
// although we have two very different code paths, the serialized
@@ -1747,7 +1765,8 @@ void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls) {
WriteStatCache(*StatCalls);
WriteSourceManagerBlock(Context.getSourceManager(), PP);
WritePreprocessor(PP);
-
+ WriteComments(Context);
+
// Keep writing types and declarations until all types and
// declarations have been written.
do {
diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp
index 44da4d72f2df..a6843e1b9efd 100644
--- a/lib/Frontend/PCHWriterDecl.cpp
+++ b/lib/Frontend/PCHWriterDecl.cpp
@@ -146,7 +146,7 @@ void PCHDeclWriter::VisitFunctionDecl(FunctionDecl *D) {
VisitValueDecl(D);
Record.push_back(D->isThisDeclarationADefinition());
if (D->isThisDeclarationADefinition())
- Writer.AddStmt(D->getBody(Context));
+ Writer.AddStmt(D->getBody());
Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
Record.push_back(D->getStorageClass()); // FIXME: stable encoding
Record.push_back(D->isInline());
@@ -172,7 +172,7 @@ void PCHDeclWriter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
// Unlike C/C++, method bodies will never be in header files.
Record.push_back(D->getBody() != 0);
if (D->getBody() != 0) {
- Writer.AddStmt(D->getBody(Context));
+ Writer.AddStmt(D->getBody());
Writer.AddDeclRef(D->getSelfDecl(), Record);
Writer.AddDeclRef(D->getCmdDecl(), Record);
}
@@ -520,7 +520,7 @@ void PCHWriter::WriteDeclsBlock(ASTContext &Context) {
// If the declaration had any attributes, write them now.
if (D->hasAttrs())
- WriteAttributeRecord(D->getAttrs(Context));
+ WriteAttributeRecord(D->getAttrs());
// Flush any expressions that were written as part of this declaration.
FlushStmts();
diff --git a/lib/Frontend/PCHWriterStmt.cpp b/lib/Frontend/PCHWriterStmt.cpp
index c63c03c8823f..5235326e9ffd 100644
--- a/lib/Frontend/PCHWriterStmt.cpp
+++ b/lib/Frontend/PCHWriterStmt.cpp
@@ -826,5 +826,4 @@ void PCHWriter::FlushStmts() {
}
StmtsToEmit.clear();
- SwitchCaseIDs.clear();
}
diff --git a/lib/Frontend/ResolveLocation.cpp b/lib/Frontend/ResolveLocation.cpp
index a5f0d1f16365..d7a9b4852a96 100644
--- a/lib/Frontend/ResolveLocation.cpp
+++ b/lib/Frontend/ResolveLocation.cpp
@@ -163,7 +163,7 @@ void StmtLocResolver::VisitStmt(Stmt *Node) {
void DeclLocResolver::VisitDeclContext(DeclContext *DC) {
DeclLocResolver DLR(Ctx, Loc);
for (DeclContext::decl_iterator
- I = DC->decls_begin(Ctx), E = DC->decls_end(Ctx); I != E; ++I) {
+ I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) {
DLR.Visit(*I);
if (DLR.Finished()) {
if (DLR.FoundIt())
@@ -211,7 +211,7 @@ void DeclLocResolver::VisitFunctionDecl(FunctionDecl *D) {
// Finally, search through the body of the function.
if (D->isThisDeclarationADefinition()) {
StmtLocResolver SLR(Ctx, Loc);
- SLR.Visit(D->getBody(Ctx));
+ SLR.Visit(D->getBody());
if (SLR.FoundIt()) {
llvm::tie(Dcl, Stm) = SLR.getResult();
// If we didn't find a more immediate 'parent' declaration for the
@@ -287,7 +287,7 @@ void LocResolverBase::FixRange(SourceRange &Range) {
void LocResolverBase::print(Decl *D) {
llvm::raw_ostream &OS = llvm::outs();
OS << "#### DECL ####\n";
- D->print(OS, Ctx);
+ D->print(OS);
OS << " <";
D->getLocStart().print(OS, Ctx.getSourceManager());
OS << " > - <";
@@ -299,7 +299,7 @@ void LocResolverBase::print(Decl *D) {
void LocResolverBase::print(Stmt *Node) {
llvm::raw_ostream &OS = llvm::outs();
OS << "#### STMT ####\n";
- Node->printPretty(OS, Ctx);
+ Node->printPretty(OS, Ctx, 0, PrintingPolicy(Ctx.getLangOptions()));
OS << " <";
Node->getLocStart().print(OS, Ctx.getSourceManager());
OS << " > - <";
diff --git a/lib/Frontend/RewriteBlocks.cpp b/lib/Frontend/RewriteBlocks.cpp
index d20d5cd152c4..bc855fa87912 100644
--- a/lib/Frontend/RewriteBlocks.cpp
+++ b/lib/Frontend/RewriteBlocks.cpp
@@ -306,39 +306,33 @@ void RewriteBlocks::RewriteMethodDecl(ObjCMethodDecl *Method) {
void RewriteBlocks::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
for (ObjCInterfaceDecl::instmeth_iterator
- I = ClassDecl->instmeth_begin(*Context),
- E = ClassDecl->instmeth_end(*Context);
+ I = ClassDecl->instmeth_begin(), E = ClassDecl->instmeth_end();
I != E; ++I)
RewriteMethodDecl(*I);
for (ObjCInterfaceDecl::classmeth_iterator
- I = ClassDecl->classmeth_begin(*Context),
- E = ClassDecl->classmeth_end(*Context);
+ I = ClassDecl->classmeth_begin(), E = ClassDecl->classmeth_end();
I != E; ++I)
RewriteMethodDecl(*I);
}
void RewriteBlocks::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
for (ObjCCategoryDecl::instmeth_iterator
- I = CatDecl->instmeth_begin(*Context),
- E = CatDecl->instmeth_end(*Context);
+ I = CatDecl->instmeth_begin(), E = CatDecl->instmeth_end();
I != E; ++I)
RewriteMethodDecl(*I);
for (ObjCCategoryDecl::classmeth_iterator
- I = CatDecl->classmeth_begin(*Context),
- E = CatDecl->classmeth_end(*Context);
+ I = CatDecl->classmeth_begin(), E = CatDecl->classmeth_end();
I != E; ++I)
RewriteMethodDecl(*I);
}
void RewriteBlocks::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
for (ObjCProtocolDecl::instmeth_iterator
- I = PDecl->instmeth_begin(*Context),
- E = PDecl->instmeth_end(*Context);
+ I = PDecl->instmeth_begin(), E = PDecl->instmeth_end();
I != E; ++I)
RewriteMethodDecl(*I);
for (ObjCProtocolDecl::classmeth_iterator
- I = PDecl->classmeth_begin(*Context),
- E = PDecl->classmeth_end(*Context);
+ I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
I != E; ++I)
RewriteMethodDecl(*I);
}
@@ -724,7 +718,8 @@ std::string RewriteBlocks::SynthesizeBlockCall(CallExpr *Exp) {
BlockCall += "((struct __block_impl *)";
std::string closureExprBufStr;
llvm::raw_string_ostream closureExprBuf(closureExprBufStr);
- Exp->getCallee()->printPretty(closureExprBuf, *Context);
+ Exp->getCallee()->printPretty(closureExprBuf, *Context, 0,
+ PrintingPolicy(LangOpts));
BlockCall += closureExprBuf.str();
BlockCall += ")->FuncPtr)";
@@ -735,7 +730,7 @@ std::string RewriteBlocks::SynthesizeBlockCall(CallExpr *Exp) {
E = Exp->arg_end(); I != E; ++I) {
std::string syncExprBufS;
llvm::raw_string_ostream Buf(syncExprBufS);
- (*I)->printPretty(Buf, *Context);
+ (*I)->printPretty(Buf, *Context, 0, PrintingPolicy(LangOpts));
BlockCall += ", " + Buf.str();
}
return BlockCall;
@@ -1088,7 +1083,7 @@ void RewriteBlocks::HandleDeclInMainFile(Decl *D) {
RewriteFunctionProtoType(FD->getType(), FD);
// FIXME: Handle CXXTryStmt
- if (CompoundStmt *Body = FD->getCompoundBody(*Context)) {
+ if (CompoundStmt *Body = FD->getCompoundBody()) {
CurFunctionDef = FD;
FD->setBody(cast_or_null<CompoundStmt>(RewriteFunctionBody(Body)));
// This synthesizes and inserts the block "impl" struct, invoke function,
@@ -1100,7 +1095,7 @@ void RewriteBlocks::HandleDeclInMainFile(Decl *D) {
}
if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
RewriteMethodDecl(MD);
- if (Stmt *Body = MD->getBody(*Context)) {
+ if (Stmt *Body = MD->getBody()) {
CurMethodDef = MD;
RewriteFunctionBody(Body);
InsertBlockLiteralsWithinMethod(MD);
@@ -1112,7 +1107,7 @@ void RewriteBlocks::HandleDeclInMainFile(Decl *D) {
RewriteBlockPointerDecl(VD);
if (VD->getInit()) {
if (BlockExpr *CBE = dyn_cast<BlockExpr>(VD->getInit())) {
- RewriteFunctionBody(CBE->getBody(*Context));
+ RewriteFunctionBody(CBE->getBody());
// We've just rewritten the block body in place.
// Now we snarf the rewritten text and stash it away for later use.
@@ -1146,8 +1141,8 @@ void RewriteBlocks::HandleDeclInMainFile(Decl *D) {
}
if (RecordDecl *RD = dyn_cast<RecordDecl>(D)) {
if (RD->isDefinition()) {
- for (RecordDecl::field_iterator i = RD->field_begin(*Context),
- e = RD->field_end(*Context); i != e; ++i) {
+ for (RecordDecl::field_iterator i = RD->field_begin(),
+ e = RD->field_end(); i != e; ++i) {
FieldDecl *FD = *i;
if (isBlockPointerType(FD->getType()))
RewriteBlockPointerDecl(FD);
diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp
index dce271070e03..cf31f2b2deab 100644
--- a/lib/Frontend/RewriteObjC.cpp
+++ b/lib/Frontend/RewriteObjC.cpp
@@ -171,7 +171,7 @@ namespace {
// Get the new text.
std::string SStr;
llvm::raw_string_ostream S(SStr);
- New->printPretty(S, *Context);
+ New->printPretty(S, *Context, 0, PrintingPolicy(LangOpts));
const std::string &Str = S.str();
// If replacement succeeded or warning disabled return with no warning.
@@ -597,8 +597,8 @@ void RewriteObjC::HandleTopLevelSingleDecl(Decl *D) {
RewriteForwardProtocolDecl(FP);
} else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
// Recurse into linkage specifications
- for (DeclContext::decl_iterator DI = LSD->decls_begin(*Context),
- DIEnd = LSD->decls_end(*Context);
+ for (DeclContext::decl_iterator DI = LSD->decls_begin(),
+ DIEnd = LSD->decls_end();
DI != DIEnd; ++DI)
HandleTopLevelSingleDecl(*DI);
}
@@ -789,13 +789,11 @@ void RewriteObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
ReplaceText(LocStart, 0, "// ", 3);
for (ObjCCategoryDecl::instmeth_iterator
- I = CatDecl->instmeth_begin(*Context),
- E = CatDecl->instmeth_end(*Context);
+ I = CatDecl->instmeth_begin(), E = CatDecl->instmeth_end();
I != E; ++I)
RewriteMethodDeclaration(*I);
for (ObjCCategoryDecl::classmeth_iterator
- I = CatDecl->classmeth_begin(*Context),
- E = CatDecl->classmeth_end(*Context);
+ I = CatDecl->classmeth_begin(), E = CatDecl->classmeth_end();
I != E; ++I)
RewriteMethodDeclaration(*I);
@@ -812,13 +810,11 @@ void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
ReplaceText(LocStart, 0, "// ", 3);
for (ObjCProtocolDecl::instmeth_iterator
- I = PDecl->instmeth_begin(*Context),
- E = PDecl->instmeth_end(*Context);
+ I = PDecl->instmeth_begin(), E = PDecl->instmeth_end();
I != E; ++I)
RewriteMethodDeclaration(*I);
for (ObjCProtocolDecl::classmeth_iterator
- I = PDecl->classmeth_begin(*Context),
- E = PDecl->classmeth_end(*Context);
+ I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
I != E; ++I)
RewriteMethodDeclaration(*I);
@@ -986,14 +982,14 @@ void RewriteObjC::RewriteImplementationDecl(Decl *OID) {
InsertText(CID->getLocStart(), "// ", 3);
for (ObjCCategoryImplDecl::instmeth_iterator
- I = IMD ? IMD->instmeth_begin(*Context) : CID->instmeth_begin(*Context),
- E = IMD ? IMD->instmeth_end(*Context) : CID->instmeth_end(*Context);
+ I = IMD ? IMD->instmeth_begin() : CID->instmeth_begin(),
+ E = IMD ? IMD->instmeth_end() : CID->instmeth_end();
I != E; ++I) {
std::string ResultStr;
ObjCMethodDecl *OMD = *I;
RewriteObjCMethodDecl(OMD, ResultStr);
SourceLocation LocStart = OMD->getLocStart();
- SourceLocation LocEnd = OMD->getCompoundBody(*Context)->getLocStart();
+ SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart();
const char *startBuf = SM->getCharacterData(LocStart);
const char *endBuf = SM->getCharacterData(LocEnd);
@@ -1002,14 +998,14 @@ void RewriteObjC::RewriteImplementationDecl(Decl *OID) {
}
for (ObjCCategoryImplDecl::classmeth_iterator
- I = IMD ? IMD->classmeth_begin(*Context) : CID->classmeth_begin(*Context),
- E = IMD ? IMD->classmeth_end(*Context) : CID->classmeth_end(*Context);
+ I = IMD ? IMD->classmeth_begin() : CID->classmeth_begin(),
+ E = IMD ? IMD->classmeth_end() : CID->classmeth_end();
I != E; ++I) {
std::string ResultStr;
ObjCMethodDecl *OMD = *I;
RewriteObjCMethodDecl(OMD, ResultStr);
SourceLocation LocStart = OMD->getLocStart();
- SourceLocation LocEnd = OMD->getCompoundBody(*Context)->getLocStart();
+ SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart();
const char *startBuf = SM->getCharacterData(LocStart);
const char *endBuf = SM->getCharacterData(LocEnd);
@@ -1017,8 +1013,8 @@ void RewriteObjC::RewriteImplementationDecl(Decl *OID) {
ResultStr.c_str(), ResultStr.size());
}
for (ObjCCategoryImplDecl::propimpl_iterator
- I = IMD ? IMD->propimpl_begin(*Context) : CID->propimpl_begin(*Context),
- E = IMD ? IMD->propimpl_end(*Context) : CID->propimpl_end(*Context);
+ I = IMD ? IMD->propimpl_begin() : CID->propimpl_begin(),
+ E = IMD ? IMD->propimpl_end() : CID->propimpl_end();
I != E; ++I) {
RewritePropertyImplDecl(*I, IMD, CID);
}
@@ -1047,17 +1043,15 @@ void RewriteObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
}
SynthesizeObjCInternalStruct(ClassDecl, ResultStr);
- for (ObjCInterfaceDecl::prop_iterator I = ClassDecl->prop_begin(*Context),
- E = ClassDecl->prop_end(*Context); I != E; ++I)
+ for (ObjCInterfaceDecl::prop_iterator I = ClassDecl->prop_begin(),
+ E = ClassDecl->prop_end(); I != E; ++I)
RewriteProperty(*I);
for (ObjCInterfaceDecl::instmeth_iterator
- I = ClassDecl->instmeth_begin(*Context),
- E = ClassDecl->instmeth_end(*Context);
+ I = ClassDecl->instmeth_begin(), E = ClassDecl->instmeth_end();
I != E; ++I)
RewriteMethodDeclaration(*I);
for (ObjCInterfaceDecl::classmeth_iterator
- I = ClassDecl->classmeth_begin(*Context),
- E = ClassDecl->classmeth_end(*Context);
+ I = ClassDecl->classmeth_begin(), E = ClassDecl->classmeth_end();
I != E; ++I)
RewriteMethodDeclaration(*I);
@@ -1149,8 +1143,7 @@ Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV,
dyn_cast<ObjCInterfaceType>(pType->getPointeeType());
// lookup which class implements the instance variable.
ObjCInterfaceDecl *clsDeclared = 0;
- iFaceDecl->getDecl()->lookupInstanceVariable(*Context,
- D->getIdentifier(),
+ iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(),
clsDeclared);
assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class");
@@ -1195,8 +1188,7 @@ Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV,
ObjCInterfaceType *iFaceDecl = dyn_cast<ObjCInterfaceType>(pType->getPointeeType());
// lookup which class implements the instance variable.
ObjCInterfaceDecl *clsDeclared = 0;
- iFaceDecl->getDecl()->lookupInstanceVariable(*Context,
- D->getIdentifier(),
+ iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(),
clsDeclared);
assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class");
@@ -1514,7 +1506,8 @@ Stmt *RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
SourceLocation());
std::string syncExprBufS;
llvm::raw_string_ostream syncExprBuf(syncExprBufS);
- syncExpr->printPretty(syncExprBuf, *Context);
+ syncExpr->printPretty(syncExprBuf, *Context, 0,
+ PrintingPolicy(LangOpts));
buf += syncExprBuf.str();
buf += ");\n";
buf += " if (_rethrow) objc_exception_throw(_rethrow);\n";
@@ -2143,7 +2136,8 @@ Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
// The pretty printer for StringLiteral handles escape characters properly.
std::string prettyBufS;
llvm::raw_string_ostream prettyBuf(prettyBufS);
- Exp->getString()->printPretty(prettyBuf, *Context);
+ Exp->getString()->printPretty(prettyBuf, *Context, 0,
+ PrintingPolicy(LangOpts));
Preamble += prettyBuf.str();
Preamble += ",";
// The minus 2 removes the begin/end double quotes.
@@ -2192,8 +2186,7 @@ QualType RewriteObjC::getSuperStructType() {
// Create fields
for (unsigned i = 0; i < 2; ++i) {
- SuperStructDecl->addDecl(*Context,
- FieldDecl::Create(*Context, SuperStructDecl,
+ SuperStructDecl->addDecl(FieldDecl::Create(*Context, SuperStructDecl,
SourceLocation(), 0,
FieldTypes[i], /*BitWidth=*/0,
/*Mutable=*/false));
@@ -2222,8 +2215,7 @@ QualType RewriteObjC::getConstantStringStructType() {
// Create fields
for (unsigned i = 0; i < 4; ++i) {
- ConstantStringDecl->addDecl(*Context,
- FieldDecl::Create(*Context,
+ ConstantStringDecl->addDecl(FieldDecl::Create(*Context,
ConstantStringDecl,
SourceLocation(), 0,
FieldTypes[i],
@@ -2889,9 +2881,9 @@ RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, const char *prefix,
if (ObjCSynthesizedProtocols.count(PDecl))
return;
- if (PDecl->instmeth_begin(*Context) != PDecl->instmeth_end(*Context)) {
- unsigned NumMethods = std::distance(PDecl->instmeth_begin(*Context),
- PDecl->instmeth_end(*Context));
+ if (PDecl->instmeth_begin() != PDecl->instmeth_end()) {
+ unsigned NumMethods = std::distance(PDecl->instmeth_begin(),
+ PDecl->instmeth_end());
/* struct _objc_protocol_method_list {
int protocol_method_count;
struct protocol_methods protocols[];
@@ -2908,10 +2900,9 @@ RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, const char *prefix,
// Output instance methods declared in this protocol.
for (ObjCProtocolDecl::instmeth_iterator
- I = PDecl->instmeth_begin(*Context),
- E = PDecl->instmeth_end(*Context);
+ I = PDecl->instmeth_begin(), E = PDecl->instmeth_end();
I != E; ++I) {
- if (I == PDecl->instmeth_begin(*Context))
+ if (I == PDecl->instmeth_begin())
Result += "\t ,{{(struct objc_selector *)\"";
else
Result += "\t ,{(struct objc_selector *)\"";
@@ -2926,8 +2917,8 @@ RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, const char *prefix,
}
// Output class methods declared in this protocol.
- unsigned NumMethods = std::distance(PDecl->classmeth_begin(*Context),
- PDecl->classmeth_end(*Context));
+ unsigned NumMethods = std::distance(PDecl->classmeth_begin(),
+ PDecl->classmeth_end());
if (NumMethods > 0) {
/* struct _objc_protocol_method_list {
int protocol_method_count;
@@ -2947,10 +2938,9 @@ RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, const char *prefix,
// Output instance methods declared in this protocol.
for (ObjCProtocolDecl::classmeth_iterator
- I = PDecl->classmeth_begin(*Context),
- E = PDecl->classmeth_end(*Context);
+ I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
I != E; ++I) {
- if (I == PDecl->classmeth_begin(*Context))
+ if (I == PDecl->classmeth_begin())
Result += "\t ,{{(struct objc_selector *)\"";
else
Result += "\t ,{(struct objc_selector *)\"";
@@ -2993,14 +2983,14 @@ RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, const char *prefix,
"{\n\t0, \"";
Result += PDecl->getNameAsString();
Result += "\", 0, ";
- if (PDecl->instmeth_begin(*Context) != PDecl->instmeth_end(*Context)) {
+ if (PDecl->instmeth_begin() != PDecl->instmeth_end()) {
Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
Result += PDecl->getNameAsString();
Result += ", ";
}
else
Result += "0, ";
- if (PDecl->classmeth_begin(*Context) != PDecl->classmeth_end(*Context)) {
+ if (PDecl->classmeth_begin() != PDecl->classmeth_end()) {
Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_CLASS_METHODS_";
Result += PDecl->getNameAsString();
Result += "\n";
@@ -3076,13 +3066,12 @@ void RewriteObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
// Build _objc_method_list for class's instance methods if needed
llvm::SmallVector<ObjCMethodDecl *, 32>
- InstanceMethods(IDecl->instmeth_begin(*Context),
- IDecl->instmeth_end(*Context));
+ InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end());
// If any of our property implementations have associated getters or
// setters, produce metadata for them as well.
- for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(*Context),
- PropEnd = IDecl->propimpl_end(*Context);
+ for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(),
+ PropEnd = IDecl->propimpl_end();
Prop != PropEnd; ++Prop) {
if ((*Prop)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
continue;
@@ -3103,8 +3092,7 @@ void RewriteObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
Result);
// Build _objc_method_list for class's class methods if needed
- RewriteObjCMethodsMetaData(IDecl->classmeth_begin(*Context),
- IDecl->classmeth_end(*Context),
+ RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
false, "CATEGORY_", FullCategoryName.c_str(),
Result);
@@ -3147,7 +3135,7 @@ void RewriteObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
Result += ClassDecl->getNameAsString();
Result += "\"\n";
- if (IDecl->instmeth_begin(*Context) != IDecl->instmeth_end(*Context)) {
+ if (IDecl->instmeth_begin() != IDecl->instmeth_end()) {
Result += "\t, (struct _objc_method_list *)"
"&_OBJC_CATEGORY_INSTANCE_METHODS_";
Result += FullCategoryName;
@@ -3155,7 +3143,7 @@ void RewriteObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
}
else
Result += "\t, 0\n";
- if (IDecl->classmeth_begin(*Context) != IDecl->classmeth_end(*Context)) {
+ if (IDecl->classmeth_begin() != IDecl->classmeth_end()) {
Result += "\t, (struct _objc_method_list *)"
"&_OBJC_CATEGORY_CLASS_METHODS_";
Result += FullCategoryName;
@@ -3210,8 +3198,8 @@ void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
}
// Build _objc_ivar_list metadata for classes ivars if needed
- unsigned NumIvars = !IDecl->ivar_empty(*Context)
- ? IDecl->ivar_size(*Context)
+ unsigned NumIvars = !IDecl->ivar_empty()
+ ? IDecl->ivar_size()
: (CDecl ? CDecl->ivar_size() : 0);
if (NumIvars > 0) {
static bool objc_ivar = false;
@@ -3249,10 +3237,9 @@ void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
ObjCInterfaceDecl::ivar_iterator IVI, IVE;
llvm::SmallVector<ObjCIvarDecl *, 8> IVars;
- if (!IDecl->ivar_empty(*Context)) {
+ if (!IDecl->ivar_empty()) {
for (ObjCImplementationDecl::ivar_iterator
- IV = IDecl->ivar_begin(*Context),
- IVEnd = IDecl->ivar_end(*Context);
+ IV = IDecl->ivar_begin(), IVEnd = IDecl->ivar_end();
IV != IVEnd; ++IV)
IVars.push_back(*IV);
IVI = IVars.begin();
@@ -3289,13 +3276,12 @@ void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
// Build _objc_method_list for class's instance methods if needed
llvm::SmallVector<ObjCMethodDecl *, 32>
- InstanceMethods(IDecl->instmeth_begin(*Context),
- IDecl->instmeth_end(*Context));
+ InstanceMethods(IDecl->instmeth_begin(), IDecl->instmeth_end());
// If any of our property implementations have associated getters or
// setters, produce metadata for them as well.
- for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(*Context),
- PropEnd = IDecl->propimpl_end(*Context);
+ for (ObjCImplDecl::propimpl_iterator Prop = IDecl->propimpl_begin(),
+ PropEnd = IDecl->propimpl_end();
Prop != PropEnd; ++Prop) {
if ((*Prop)->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
continue;
@@ -3315,8 +3301,7 @@ void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
true, "", IDecl->getNameAsCString(), Result);
// Build _objc_method_list for class's class methods if needed
- RewriteObjCMethodsMetaData(IDecl->classmeth_begin(*Context),
- IDecl->classmeth_end(*Context),
+ RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
false, "", IDecl->getNameAsCString(), Result);
// Protocols referenced in class declaration?
@@ -3389,7 +3374,7 @@ void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
// Set 'ivars' field for root class to 0. ObjC1 runtime does not use it.
// 'info' field is initialized to CLS_META(2) for metaclass
Result += ", 0,2, sizeof(struct _objc_class), 0";
- if (IDecl->classmeth_begin(*Context) != IDecl->classmeth_end(*Context)) {
+ if (IDecl->classmeth_begin() != IDecl->classmeth_end()) {
Result += "\n\t, (struct _objc_method_list *)&_OBJC_CLASS_METHODS_";
Result += IDecl->getNameAsString();
Result += "\n";
@@ -3442,7 +3427,7 @@ void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
}
else
Result += ",0";
- if (IDecl->instmeth_begin(*Context) != IDecl->instmeth_end(*Context)) {
+ if (IDecl->instmeth_begin() != IDecl->instmeth_end()) {
Result += ", (struct _objc_method_list *)&_OBJC_INSTANCE_METHODS_";
Result += CDecl->getNameAsString();
Result += ", 0\n\t";
@@ -4552,7 +4537,7 @@ void RewriteObjC::HandleDeclInMainFile(Decl *D) {
RewriteBlocksInFunctionProtoType(FD->getType(), FD);
// FIXME: If this should support Obj-C++, support CXXTryStmt
- if (CompoundStmt *Body = FD->getCompoundBody(*Context)) {
+ if (CompoundStmt *Body = FD->getCompoundBody()) {
CurFunctionDef = FD;
CollectPropertySetters(Body);
CurrentBody = Body;
@@ -4572,7 +4557,7 @@ void RewriteObjC::HandleDeclInMainFile(Decl *D) {
return;
}
if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
- if (CompoundStmt *Body = MD->getBody()) {
+ if (CompoundStmt *Body = MD->getCompoundBody()) {
CurMethodDef = MD;
CollectPropertySetters(Body);
CurrentBody = Body;
@@ -4636,8 +4621,8 @@ void RewriteObjC::HandleDeclInMainFile(Decl *D) {
}
if (RecordDecl *RD = dyn_cast<RecordDecl>(D)) {
if (RD->isDefinition()) {
- for (RecordDecl::field_iterator i = RD->field_begin(*Context),
- e = RD->field_end(*Context); i != e; ++i) {
+ for (RecordDecl::field_iterator i = RD->field_begin(),
+ e = RD->field_end(); i != e; ++i) {
FieldDecl *FD = *i;
if (isTopLevelBlockPointerType(FD->getType()))
RewriteBlockPointerDecl(FD);
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
index 81ea606f0d9f..6f1043ae7353 100644
--- a/lib/Lex/Lexer.cpp
+++ b/lib/Lex/Lexer.cpp
@@ -903,7 +903,10 @@ bool Lexer::SkipBCPLComment(Token &Result, const char *CurPtr) {
} while (C != '\n' && C != '\r');
// Found but did not consume the newline.
-
+ if (PP)
+ PP->HandleComment(SourceRange(getSourceLocation(BufferPtr),
+ getSourceLocation(CurPtr)));
+
// If we are returning comments as tokens, return this comment as a token.
if (inKeepCommentMode())
return SaveBCPLComment(Result, CurPtr);
@@ -1146,6 +1149,10 @@ bool Lexer::SkipBlockComment(Token &Result, const char *CurPtr) {
C = *CurPtr++;
}
+ if (PP)
+ PP->HandleComment(SourceRange(getSourceLocation(BufferPtr),
+ getSourceLocation(CurPtr)));
+
// If we are returning comments as tokens, return this comment as a token.
if (inKeepCommentMode()) {
FormTokenWithChars(Result, CurPtr, tok::comment);
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index 3227d1cf09c5..bb0b71e22682 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -19,6 +19,7 @@
#include "clang/Lex/LexDiagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
+#include <algorithm>
using namespace clang;
// Out-of-line destructor to provide a home for the class.
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index 24ee5d8a8f92..9f0c15f59e49 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -476,3 +476,26 @@ void Preprocessor::HandleIdentifier(Token &Identifier) {
if (II.isExtensionToken() && !DisableMacroExpansion)
Diag(Identifier, diag::ext_token_used);
}
+
+void Preprocessor::AddCommentHandler(CommentHandler *Handler) {
+ assert(Handler && "NULL comment handler");
+ assert(std::find(CommentHandlers.begin(), CommentHandlers.end(), Handler) ==
+ CommentHandlers.end() && "Comment handler already registered");
+ CommentHandlers.push_back(Handler);
+}
+
+void Preprocessor::RemoveCommentHandler(CommentHandler *Handler) {
+ std::vector<CommentHandler *>::iterator Pos
+ = std::find(CommentHandlers.begin(), CommentHandlers.end(), Handler);
+ assert(Pos != CommentHandlers.end() && "Comment handler not registered");
+ CommentHandlers.erase(Pos);
+}
+
+void Preprocessor::HandleComment(SourceRange Comment) {
+ for (std::vector<CommentHandler *>::iterator H = CommentHandlers.begin(),
+ HEnd = CommentHandlers.end();
+ H != HEnd; ++H)
+ (*H)->HandleComment(*this, Comment);
+}
+
+CommentHandler::~CommentHandler() { }
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index ff602e8ba79b..4a3532c4103b 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -802,7 +802,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
SourceLocation EndProtoLoc;
llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
- DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size());
+ DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size());
DS.SetRangeEnd(EndProtoLoc);
continue;
@@ -859,7 +859,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
SourceLocation EndProtoLoc;
llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
- DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size());
+ DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size());
DS.SetRangeEnd(EndProtoLoc);
@@ -1066,7 +1066,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
SourceLocation EndProtoLoc;
llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
- DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size());
+ DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size());
DS.SetRangeEnd(EndProtoLoc);
Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id)
@@ -1179,7 +1179,7 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, int& isInvalid,
SourceLocation EndProtoLoc;
llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl;
ParseObjCProtocolReferences(ProtocolDecl, false, EndProtoLoc);
- DS.setProtocolQualifiers(&ProtocolDecl[0], ProtocolDecl.size());
+ DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size());
DS.SetRangeEnd(EndProtoLoc);
return true;
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 225f9261ef8f..373d22fd9f4f 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -1277,16 +1277,28 @@ void Parser::ParseConstructorInitializer(DeclPtrTy ConstructorDecl) {
/// '::'[opt] nested-name-specifier[opt] class-name
/// identifier
Parser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) {
- // FIXME: parse '::'[opt] nested-name-specifier[opt]
-
- if (Tok.isNot(tok::identifier)) {
+ // parse '::'[opt] nested-name-specifier[opt]
+ CXXScopeSpec SS;
+ ParseOptionalCXXScopeSpecifier(SS);
+ TypeTy *TemplateTypeTy = 0;
+ if (Tok.is(tok::annot_template_id)) {
+ TemplateIdAnnotation *TemplateId
+ = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
+ if (TemplateId->Kind == TNK_Type_template) {
+ AnnotateTemplateIdTokenAsType(&SS);
+ assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
+ TemplateTypeTy = Tok.getAnnotationValue();
+ }
+ // FIXME. May need to check for TNK_Dependent_template as well.
+ }
+ if (!TemplateTypeTy && Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_member_or_base_name);
return true;
}
-
+
// Get the identifier. This may be a member name or a class name,
// but we'll let the semantic analysis determine which it is.
- IdentifierInfo *II = Tok.getIdentifierInfo();
+ IdentifierInfo *II = Tok.is(tok::identifier) ? Tok.getIdentifierInfo() : 0;
SourceLocation IdLoc = ConsumeToken();
// Parse the '('.
@@ -1306,7 +1318,8 @@ Parser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) {
SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
- return Actions.ActOnMemInitializer(ConstructorDecl, CurScope, II, IdLoc,
+ return Actions.ActOnMemInitializer(ConstructorDecl, CurScope, SS, II,
+ TemplateTypeTy, IdLoc,
LParenLoc, ArgExprs.take(),
ArgExprs.size(), CommaLocs.data(),
RParenLoc);
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 13b32acd5b29..cd7618f66536 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -777,7 +777,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression,
case tok::annot_cxxscope: // [C++] id-expression: qualified-id
case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id
- // template-id
+ case tok::annot_template_id: // [C++] template-id
Res = ParseCXXIdExpression(isAddressOfOperand);
return ParsePostfixExpressionSuffix(move(Res));
@@ -1172,17 +1172,18 @@ Parser::OwningExprResult Parser::ParseBuiltinPrimaryExpression() {
Comps.back().LocEnd =
MatchRHSPunctuation(tok::r_square, Comps.back().LocStart);
- } else if (Tok.is(tok::r_paren)) {
- if (Ty.isInvalid())
+ } else {
+ if (Tok.isNot(tok::r_paren)) {
+ MatchRHSPunctuation(tok::r_paren, LParenLoc);
+ Res = ExprError();
+ } else if (Ty.isInvalid()) {
Res = ExprError();
- else
+ } else {
Res = Actions.ActOnBuiltinOffsetOf(CurScope, StartLoc, TypeLoc,
Ty.get(), &Comps[0],
Comps.size(), ConsumeParen());
+ }
break;
- } else {
- // Error occurred.
- return ExprError();
}
}
break;
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index d89f1e172ffb..1220b2d27b4f 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -207,13 +207,13 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS) {
/// operator-function-id
/// conversion-function-id [TODO]
/// '~' class-name [TODO]
-/// template-id [TODO]
+/// template-id
///
/// qualified-id:
/// '::'[opt] nested-name-specifier 'template'[opt] unqualified-id
/// '::' identifier
/// '::' operator-function-id
-/// '::' template-id [TODO]
+/// '::' template-id
///
/// nested-name-specifier:
/// type-name '::'
@@ -264,7 +264,7 @@ Parser::OwningExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) {
// operator-function-id
// conversion-function-id
// '~' class-name [TODO]
- // template-id [TODO]
+ // template-id
//
switch (Tok.getKind()) {
default:
@@ -294,6 +294,29 @@ Parser::OwningExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) {
return ExprError();
}
+ case tok::annot_template_id: {
+ TemplateIdAnnotation *TemplateId
+ = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
+ assert((TemplateId->Kind == TNK_Function_template ||
+ TemplateId->Kind == TNK_Dependent_template_name) &&
+ "A template type name is not an ID expression");
+
+ ASTTemplateArgsPtr TemplateArgsPtr(Actions,
+ TemplateId->getTemplateArgs(),
+ TemplateId->getTemplateArgIsType(),
+ TemplateId->NumArgs);
+
+ OwningExprResult Result
+ = Actions.ActOnTemplateIdExpr(TemplateTy::make(TemplateId->Template),
+ TemplateId->TemplateNameLoc,
+ TemplateId->LAngleLoc,
+ TemplateArgsPtr,
+ TemplateId->getTemplateArgLocations(),
+ TemplateId->RAngleLoc);
+ ConsumeToken(); // Consume the template-id token
+ return move(Result);
+ }
+
} // switch.
assert(0 && "The switch was supposed to take care everything.");
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 29d1d8792e1a..9771cf7b8474 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -20,6 +20,19 @@
#include "ParsePragma.h"
using namespace clang;
+/// \brief A comment handler that passes comments found by the preprocessor
+/// to the parser action.
+class ActionCommentHandler : public CommentHandler {
+ Action &Actions;
+
+public:
+ explicit ActionCommentHandler(Action &Actions) : Actions(Actions) { }
+
+ virtual void HandleComment(Preprocessor &PP, SourceRange Comment) {
+ Actions.ActOnComment(Comment);
+ }
+};
+
Parser::Parser(Preprocessor &pp, Action &actions)
: CrashInfo(*this), PP(pp), Actions(actions), Diags(PP.getDiagnostics()),
GreaterThanIsOperator(true) {
@@ -43,6 +56,9 @@ Parser::Parser(Preprocessor &pp, Action &actions)
WeakHandler.reset(new
PragmaWeakHandler(&PP.getIdentifierTable().get("weak"), actions));
PP.AddPragmaHandler(0, WeakHandler.get());
+
+ CommentHandler.reset(new ActionCommentHandler(actions));
+ PP.AddCommentHandler(CommentHandler.get());
}
/// If a crash happens while the parser is active, print out a line indicating
@@ -294,6 +310,7 @@ Parser::~Parser() {
UnusedHandler.reset();
PP.RemovePragmaHandler(0, WeakHandler.get());
WeakHandler.reset();
+ PP.RemoveCommentHandler(CommentHandler.get());
}
/// Initialize - Warm up the parser.
diff --git a/lib/Rewrite/Rewriter.cpp b/lib/Rewrite/Rewriter.cpp
index d81c38d6a466..ec5a60412d13 100644
--- a/lib/Rewrite/Rewriter.cpp
+++ b/lib/Rewrite/Rewriter.cpp
@@ -218,7 +218,7 @@ bool Rewriter::ReplaceStmt(Stmt *From, Stmt *To) {
// Get the new text.
std::string SStr;
llvm::raw_string_ostream S(SStr);
- To->printPretty(S);
+ To->printPretty(S, 0, PrintingPolicy(*LangOpts));
const std::string &Str = S.str();
ReplaceText(From->getLocStart(), Size, &Str[0], Str.size());
diff --git a/lib/Sema/JumpDiagnostics.cpp b/lib/Sema/JumpDiagnostics.cpp
index 425d80443955..ae863f2df1ee 100644
--- a/lib/Sema/JumpDiagnostics.cpp
+++ b/lib/Sema/JumpDiagnostics.cpp
@@ -77,11 +77,11 @@ JumpScopeChecker::JumpScopeChecker(Stmt *Body, Sema &s) : S(s) {
/// GetDiagForGotoScopeDecl - If this decl induces a new goto scope, return a
/// diagnostic that should be emitted if control goes over it. If not, return 0.
-static unsigned GetDiagForGotoScopeDecl(ASTContext &Context, const Decl *D) {
+static unsigned GetDiagForGotoScopeDecl(const Decl *D) {
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
if (VD->getType()->isVariablyModifiedType())
return diag::note_protected_by_vla;
- if (VD->hasAttr<CleanupAttr>(Context))
+ if (VD->hasAttr<CleanupAttr>())
return diag::note_protected_by_cleanup;
} else if (const TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
if (TD->getUnderlyingType()->isVariablyModifiedType())
@@ -125,7 +125,7 @@ void JumpScopeChecker::BuildScopeInformation(Stmt *S, unsigned ParentScope) {
for (DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end();
I != E; ++I) {
// If this decl causes a new scope, push and switch to it.
- if (unsigned Diag = GetDiagForGotoScopeDecl(this->S.Context, *I)) {
+ if (unsigned Diag = GetDiagForGotoScopeDecl(*I)) {
Scopes.push_back(GotoScope(ParentScope, Diag, (*I)->getLocation()));
ParentScope = Scopes.size()-1;
}
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index c37f66dae907..d1e8e2104d50 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -345,3 +345,7 @@ Sema::SemaDiagnosticBuilder::~SemaDiagnosticBuilder() {
= SemaRef.ActiveTemplateInstantiations.back();
}
}
+
+void Sema::ActOnComment(SourceRange Comment) {
+ Context.Comments.push_back(Comment);
+}
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 2d27ccc77839..7af80c0261e4 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -29,9 +29,9 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/OwningPtr.h"
+#include <deque>
#include <list>
#include <string>
-#include <queue>
#include <vector>
namespace llvm {
@@ -86,6 +86,7 @@ namespace clang {
class ObjCMethodDecl;
class ObjCPropertyDecl;
class ObjCContainerDecl;
+ class FunctionProtoType;
class BasePaths;
struct MemberLookupCriteria;
class CXXTemporary;
@@ -362,6 +363,8 @@ public:
return CurBlock ? CurBlock->SwitchStack : FunctionSwitchStack;
}
+ virtual void ActOnComment(SourceRange Comment);
+
//===--------------------------------------------------------------------===//
// Type Analysis / Processing: SemaType.cpp.
//
@@ -392,6 +395,9 @@ public:
DeclarationName GetNameForDeclarator(Declarator &D);
bool CheckSpecifiedExceptionType(QualType T, const SourceRange &Range);
bool CheckDistantExceptionSpec(QualType T);
+ bool CheckEquivalentExceptionSpec(
+ const FunctionProtoType *Old, SourceLocation OldLoc,
+ const FunctionProtoType *New, SourceLocation NewLoc);
QualType ObjCGetTypeForMethodDefinition(DeclPtrTy D);
@@ -406,6 +412,9 @@ public:
QualType getQualifiedNameType(const CXXScopeSpec &SS, QualType T);
+ QualType BuildTypeofExprType(Expr *E);
+ QualType BuildDecltypeType(Expr *E);
+
//===--------------------------------------------------------------------===//
// Symbol table / Decl tracking callbacks: SemaDecl.cpp.
//
@@ -482,7 +491,7 @@ public:
void DiagnoseUnusedParameters(InputIterator Param, InputIterator ParamEnd) {
for (; Param != ParamEnd; ++Param) {
if (!(*Param)->isUsed() && (*Param)->getDeclName() &&
- !(*Param)->template hasAttr<UnusedAttr>(Context))
+ !(*Param)->template hasAttr<UnusedAttr>())
Diag((*Param)->getLocation(), diag::warn_unused_parameter)
<< (*Param)->getDeclName();
}
@@ -679,7 +688,7 @@ public:
OR_Deleted ///< Overload resoltuion refers to a deleted function.
};
- typedef llvm::SmallPtrSet<FunctionDecl *, 16> FunctionSet;
+ typedef llvm::SmallPtrSet<AnyFunctionDecl, 16> FunctionSet;
typedef llvm::SmallPtrSet<NamespaceDecl *, 16> AssociatedNamespaceSet;
typedef llvm::SmallPtrSet<CXXRecordDecl *, 16> AssociatedClassSet;
@@ -698,6 +707,9 @@ public:
bool SuppressUserConversions = false,
bool ForceRValue = false);
void AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
+ bool HasExplicitTemplateArgs,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions = false,
@@ -744,6 +756,9 @@ public:
FunctionDecl *ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
DeclarationName UnqualifiedName,
+ bool HasExplicitTemplateArgs,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
SourceLocation LParenLoc,
Expr **Args, unsigned NumArgs,
SourceLocation *CommaLocs,
@@ -1398,7 +1413,11 @@ public:
bool HasTrailingLParen,
const CXXScopeSpec *SS,
bool isAddressOfOperand = false);
-
+ OwningExprResult BuildDeclarationNameExpr(SourceLocation Loc, NamedDecl *D,
+ bool HasTrailingLParen,
+ const CXXScopeSpec *SS,
+ bool isAddressOfOperand);
+
virtual OwningExprResult ActOnPredefinedExpr(SourceLocation Loc,
tok::TokenKind Kind);
virtual OwningExprResult ActOnNumericConstant(const Token &);
@@ -1594,9 +1613,9 @@ public:
QualType DeclInitType,
Expr **Exprs, unsigned NumExprs);
- /// MarcDestructorReferenced - Prepare for calling destructor on the
+ /// MarkDestructorReferenced - Prepare for calling destructor on the
/// constructed decl.
- void MarcDestructorReferenced(SourceLocation Loc, QualType DeclInitType);
+ void MarkDestructorReferenced(SourceLocation Loc, QualType DeclInitType);
/// DefineImplicitDefaultConstructor - Checks for feasibility of
/// defining this constructor as the default constructor.
@@ -1884,7 +1903,9 @@ public:
virtual MemInitResult ActOnMemInitializer(DeclPtrTy ConstructorD,
Scope *S,
+ const CXXScopeSpec &SS,
IdentifierInfo *MemberOrBase,
+ TypeTy *TemplateTypeTy,
SourceLocation IdLoc,
SourceLocation LParenLoc,
ExprTy **Args, unsigned NumArgs,
@@ -2068,6 +2089,20 @@ public:
SourceLocation *TemplateArgLocs,
SourceLocation RAngleLoc);
+ OwningExprResult BuildTemplateIdExpr(TemplateName Template,
+ SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc,
+ const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs,
+ SourceLocation RAngleLoc);
+
+ virtual OwningExprResult ActOnTemplateIdExpr(TemplateTy Template,
+ SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc,
+ ASTTemplateArgsPtr TemplateArgs,
+ SourceLocation *TemplateArgLocs,
+ SourceLocation RAngleLoc);
+
virtual TemplateTy ActOnDependentTemplateName(SourceLocation TemplateKWLoc,
const IdentifierInfo &Name,
SourceLocation NameLoc,
@@ -2134,6 +2169,7 @@ public:
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc,
+ bool PartialTemplateArgs,
TemplateArgumentListBuilder &Converted);
bool CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
@@ -2225,7 +2261,10 @@ public:
TDK_TooManyArguments,
/// \brief When performing template argument deduction for a class
/// template, there were too few call arguments.
- TDK_TooFewArguments
+ TDK_TooFewArguments,
+ /// \brief The explicitly-specified template arguments were not valid
+ /// template arguments for the given template.
+ TDK_InvalidExplicitArguments
};
/// \brief Provides information about an attempted template argument
@@ -2307,6 +2346,9 @@ public:
TemplateDeductionResult
DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+ bool HasExplicitTemplateArgs,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
Expr **Args, unsigned NumArgs,
FunctionDecl *&Specialization,
TemplateDeductionInfo &Info);
@@ -2323,7 +2365,7 @@ public:
/// \brief A template instantiation that is currently in progress.
struct ActiveTemplateInstantiation {
/// \brief The kind of template instantiation we are performing
- enum {
+ enum InstantiationKind {
/// We are instantiating a template declaration. The entity is
/// the declaration we're instantiating (e.g., a CXXRecordDecl).
TemplateInstantiation,
@@ -2335,13 +2377,16 @@ public:
/// FIXME: Use a TemplateArgumentList
DefaultTemplateArgumentInstantiation,
- /// We are performing template argument deduction for a class
- /// template partial specialization. The Entity is the class
- /// template partial specialization, and
- /// TemplateArgs/NumTemplateArgs provides the deduced template
- /// arguments.
- /// FIXME: Use a TemplateArgumentList
- PartialSpecDeductionInstantiation
+ /// We are substituting explicit template arguments provided for
+ /// a function template. The entity is a FunctionTemplateDecl.
+ ExplicitTemplateArgumentSubstitution,
+
+ /// We are substituting template argument determined as part of
+ /// template argument deduction for either a class template
+ /// partial specialization or a function template. The
+ /// Entity is either a ClassTemplatePartialSpecializationDecl or
+ /// a FunctionTemplateDecl.
+ DeducedTemplateArgumentSubstitution
} Kind;
/// \brief The point of instantiation within the source code.
@@ -2375,7 +2420,8 @@ public:
return true;
case DefaultTemplateArgumentInstantiation:
- case PartialSpecDeductionInstantiation:
+ case ExplicitTemplateArgumentSubstitution:
+ case DeducedTemplateArgumentSubstitution:
return X.TemplateArgs == Y.TemplateArgs;
}
@@ -2432,6 +2478,15 @@ public:
unsigned NumTemplateArgs,
SourceRange InstantiationRange = SourceRange());
+ /// \brief Note that we are instantiating a default argument in a
+ /// template-id.
+ InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
+ FunctionTemplateDecl *FunctionTemplate,
+ const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs,
+ ActiveTemplateInstantiation::InstantiationKind Kind,
+ SourceRange InstantiationRange = SourceRange());
+
/// \brief Note that we are instantiating as part of template
/// argument deduction for a class template partial
/// specialization.
@@ -2574,7 +2629,7 @@ public:
/// \brief The queue of implicit template instantiations that are required
/// but have not yet been performed.
- std::queue<PendingImplicitInstantiation> PendingImplicitInstantiations;
+ std::deque<PendingImplicitInstantiation> PendingImplicitInstantiations;
void PerformPendingImplicitInstantiations();
@@ -2629,7 +2684,8 @@ public:
const TemplateArgumentList &TemplateArgs);
void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
- FunctionDecl *Function);
+ FunctionDecl *Function,
+ bool Recursive = false);
void InstantiateVariableDefinition(VarDecl *Var);
NamedDecl *InstantiateCurrentDeclRef(NamedDecl *D);
diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp
index cbfa56a6911f..1bf8444c42b7 100644
--- a/lib/Sema/SemaAttr.cpp
+++ b/lib/Sema/SemaAttr.cpp
@@ -205,7 +205,7 @@ void Sema::ActOnPragmaUnused(ExprTy **Exprs, unsigned NumExprs,
// Otherwise, add the 'unused' attribute to each referenced declaration.
for (unsigned i = 0; i < NumExprs; ++i) {
DeclRefExpr *DR = (DeclRefExpr*) Exprs[i];
- DR->getDecl()->addAttr(Context, ::new (Context) UnusedAttr());
+ DR->getDecl()->addAttr(::new (Context) UnusedAttr());
DR->Destroy(Context);
}
}
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index f6d6623f9a20..4eed01872246 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -166,7 +166,7 @@ Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) {
// handlers.
// Printf checking.
- if (const FormatAttr *Format = FDecl->getAttr<FormatAttr>(Context)) {
+ if (const FormatAttr *Format = FDecl->getAttr<FormatAttr>()) {
if (Format->getType() == "printf") {
bool HasVAListArg = Format->getFirstArg() == 0;
if (!HasVAListArg) {
@@ -178,7 +178,7 @@ Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) {
HasVAListArg ? 0 : Format->getFirstArg() - 1);
}
}
- for (const Attr *attr = FDecl->getAttrs(Context);
+ for (const Attr *attr = FDecl->getAttrs();
attr; attr = attr->getNext()) {
if (const NonNullAttr *NonNull = dyn_cast<NonNullAttr>(attr))
CheckNonNullArguments(NonNull, TheCall);
@@ -192,7 +192,7 @@ Sema::CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall) {
OwningExprResult TheCallResult(Owned(TheCall));
// Printf checking.
- const FormatAttr *Format = NDecl->getAttr<FormatAttr>(Context);
+ const FormatAttr *Format = NDecl->getAttr<FormatAttr>();
if (!Format)
return move(TheCallResult);
const VarDecl *V = dyn_cast<VarDecl>(NDecl);
@@ -717,8 +717,6 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
if (E->isTypeDependent() || E->isValueDependent())
return false;
- E = E->IgnoreParenCasts();
-
switch (E->getStmtClass()) {
case Stmt::ConditionalOperatorClass: {
const ConditionalOperator *C = cast<ConditionalOperator>(E);
@@ -763,6 +761,28 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
return SemaCheckStringLiteral(Init, TheCall,
HasVAListArg, format_idx, firstDataArg);
}
+
+ // For vprintf* functions (i.e., HasVAListArg==true), we add a
+ // special check to see if the format string is a function parameter
+ // of the function calling the printf function. If the function
+ // has an attribute indicating it is a printf-like function, then we
+ // should suppress warnings concerning non-literals being used in a call
+ // to a vprintf function. For example:
+ //
+ // void
+ // logmessage(char const *fmt __attribute__ (format (printf, 1, 2)), ...){
+ // va_list ap;
+ // va_start(ap, fmt);
+ // vprintf(fmt, ap); // Do NOT emit a warning about "fmt".
+ // ...
+ //
+ //
+ // FIXME: We don't have full attribute support yet, so just check to see
+ // if the argument is a DeclRefExpr that references a parameter. We'll
+ // add proper support for checking the attribute later.
+ if (HasVAListArg)
+ if (isa<ParmVarDecl>(VD))
+ return true;
}
return false;
@@ -774,7 +794,7 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall,
= dyn_cast<ImplicitCastExpr>(CE->getCallee())) {
if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ICE->getSubExpr())) {
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(DRE->getDecl())) {
- if (const FormatArgAttr *FA = FD->getAttr<FormatArgAttr>(Context)) {
+ if (const FormatArgAttr *FA = FD->getAttr<FormatArgAttr>()) {
unsigned ArgIndex = FA->getFormatIdx();
const Expr *Arg = CE->getArg(ArgIndex - 1);
@@ -901,29 +921,6 @@ Sema::CheckPrintfArguments(const CallExpr *TheCall, bool HasVAListArg,
firstDataArg))
return; // Literal format string found, check done!
- // For vprintf* functions (i.e., HasVAListArg==true), we add a
- // special check to see if the format string is a function parameter
- // of the function calling the printf function. If the function
- // has an attribute indicating it is a printf-like function, then we
- // should suppress warnings concerning non-literals being used in a call
- // to a vprintf function. For example:
- //
- // void
- // logmessage(char const *fmt __attribute__ (format (printf, 1, 2)), ...) {
- // va_list ap;
- // va_start(ap, fmt);
- // vprintf(fmt, ap); // Do NOT emit a warning about "fmt".
- // ...
- //
- //
- // FIXME: We don't have full attribute support yet, so just check to see
- // if the argument is a DeclRefExpr that references a parameter. We'll
- // add proper support for checking the attribute later.
- if (HasVAListArg)
- if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(OrigFormatExpr))
- if (isa<ParmVarDecl>(DR->getDecl()))
- return;
-
// If there are no arguments specified, warn with -Wformat-security, otherwise
// warn only with -Wformat-nonliteral.
if (TheCall->getNumArgs() == format_idx+1)
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 13162d8e8ea9..1fd569729a37 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -256,7 +256,7 @@ static bool AllowOverloadingOfFunction(Decl *PrevDecl, ASTContext &Context) {
if (isa<OverloadedFunctionDecl>(PrevDecl))
return true;
- return PrevDecl->getAttr<OverloadableAttr>(Context) != 0;
+ return PrevDecl->getAttr<OverloadableAttr>() != 0;
}
/// Add this decl to the scope shadowed decl chains.
@@ -273,7 +273,7 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S) {
// Add scoped declarations into their context, so that they can be
// found later. Declarations without a context won't be inserted
// into any context.
- CurContext->addDecl(Context, D);
+ CurContext->addDecl(D);
// C++ [basic.scope]p4:
// -- exactly one declaration shall declare a class name or
@@ -612,8 +612,8 @@ void Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
/// DeclhasAttr - returns true if decl Declaration already has the target
/// attribute.
static bool
-DeclHasAttr(ASTContext &Context, const Decl *decl, const Attr *target) {
- for (const Attr *attr = decl->getAttrs(Context); attr; attr = attr->getNext())
+DeclHasAttr(const Decl *decl, const Attr *target) {
+ for (const Attr *attr = decl->getAttrs(); attr; attr = attr->getNext())
if (attr->getKind() == target->getKind())
return true;
@@ -622,11 +622,11 @@ DeclHasAttr(ASTContext &Context, const Decl *decl, const Attr *target) {
/// MergeAttributes - append attributes from the Old decl to the New one.
static void MergeAttributes(Decl *New, Decl *Old, ASTContext &C) {
- for (const Attr *attr = Old->getAttrs(C); attr; attr = attr->getNext()) {
- if (!DeclHasAttr(C, New, attr) && attr->isMerged()) {
+ for (const Attr *attr = Old->getAttrs(); attr; attr = attr->getNext()) {
+ if (!DeclHasAttr(New, attr) && attr->isMerged()) {
Attr *NewAttr = attr->clone(C);
NewAttr->setInherited(true);
- New->addAttr(C, NewAttr);
+ New->addAttr(NewAttr);
}
}
}
@@ -1123,8 +1123,8 @@ Sema::DeclPtrTy Sema::ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
bool Sema::InjectAnonymousStructOrUnionMembers(Scope *S, DeclContext *Owner,
RecordDecl *AnonRecord) {
bool Invalid = false;
- for (RecordDecl::field_iterator F = AnonRecord->field_begin(Context),
- FEnd = AnonRecord->field_end(Context);
+ for (RecordDecl::field_iterator F = AnonRecord->field_begin(),
+ FEnd = AnonRecord->field_end();
F != FEnd; ++F) {
if ((*F)->getDeclName()) {
NamedDecl *PrevDecl = LookupQualifiedName(Owner, (*F)->getDeclName(),
@@ -1147,7 +1147,7 @@ bool Sema::InjectAnonymousStructOrUnionMembers(Scope *S, DeclContext *Owner,
// definition, the members of the anonymous union are
// considered to have been defined in the scope in which the
// anonymous union is declared.
- Owner->makeDeclVisibleInContext(Context, *F);
+ Owner->makeDeclVisibleInContext(*F);
S->AddDecl(DeclPtrTy::make(*F));
IdResolver.AddDecl(*F);
}
@@ -1213,8 +1213,8 @@ Sema::DeclPtrTy Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
// The member-specification of an anonymous union shall only
// define non-static data members. [Note: nested types and
// functions cannot be declared within an anonymous union. ]
- for (DeclContext::decl_iterator Mem = Record->decls_begin(Context),
- MemEnd = Record->decls_end(Context);
+ for (DeclContext::decl_iterator Mem = Record->decls_begin(),
+ MemEnd = Record->decls_end();
Mem != MemEnd; ++Mem) {
if (FieldDecl *FD = dyn_cast<FieldDecl>(*Mem)) {
// C++ [class.union]p3:
@@ -1302,7 +1302,7 @@ Sema::DeclPtrTy Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
// Add the anonymous struct/union object to the current
// context. We'll be referencing this object when we refer to one of
// its members.
- Owner->addDecl(Context, Anon);
+ Owner->addDecl(Anon);
// Inject the members of the anonymous struct/union into the owning
// context and into the identifier resolver chain for name lookup
@@ -1851,8 +1851,7 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
if (Expr *E = (Expr*) D.getAsmLabel()) {
// The parser guarantees this is a string.
StringLiteral *SE = cast<StringLiteral>(E);
- NewVD->addAttr(Context,
- ::new (Context) AsmLabelAttr(std::string(SE->getStrData(),
+ NewVD->addAttr(::new (Context) AsmLabelAttr(std::string(SE->getStrData(),
SE->getByteLength())));
}
@@ -1931,11 +1930,11 @@ void Sema::CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
}
if (NewVD->hasLocalStorage() && T.isObjCGCWeak()
- && !NewVD->hasAttr<BlocksAttr>(Context))
+ && !NewVD->hasAttr<BlocksAttr>())
Diag(NewVD->getLocation(), diag::warn_attribute_weak_on_local);
bool isVM = T->isVariablyModifiedType();
- if (isVM || NewVD->hasAttr<CleanupAttr>(Context))
+ if (isVM || NewVD->hasAttr<CleanupAttr>())
CurFunctionNeedsScopeChecking = true;
if ((isVM && NewVD->hasLinkage()) ||
@@ -1990,12 +1989,12 @@ void Sema::CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
return NewVD->setInvalidDecl();
}
- if (!NewVD->hasLocalStorage() && NewVD->hasAttr<BlocksAttr>(Context)) {
+ if (!NewVD->hasLocalStorage() && NewVD->hasAttr<BlocksAttr>()) {
Diag(NewVD->getLocation(), diag::err_block_on_nonlocal);
return NewVD->setInvalidDecl();
}
- if (isVM && NewVD->hasAttr<BlocksAttr>(Context)) {
+ if (isVM && NewVD->hasAttr<BlocksAttr>()) {
Diag(NewVD->getLocation(), diag::err_block_on_vm);
return NewVD->setInvalidDecl();
}
@@ -2251,8 +2250,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
if (Expr *E = (Expr*) D.getAsmLabel()) {
// The parser guarantees this is a string.
StringLiteral *SE = cast<StringLiteral>(E);
- NewFD->addAttr(Context,
- ::new (Context) AsmLabelAttr(std::string(SE->getStrData(),
+ NewFD->addAttr(::new (Context) AsmLabelAttr(std::string(SE->getStrData(),
SE->getByteLength())));
}
@@ -2371,7 +2369,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
ProcessDeclAttributes(S, NewFD, D);
AddKnownFunctionAttributes(NewFD);
- if (OverloadableAttrRequired && !NewFD->getAttr<OverloadableAttr>(Context)) {
+ if (OverloadableAttrRequired && !NewFD->getAttr<OverloadableAttr>()) {
// If a function name is overloadable in C, then every function
// with that name must be marked "overloadable".
Diag(NewFD->getLocation(), diag::err_attribute_overloadable_missing)
@@ -2379,7 +2377,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
if (PrevDecl)
Diag(PrevDecl->getLocation(),
diag::note_attribute_overloadable_prev_overload);
- NewFD->addAttr(Context, ::new (Context) OverloadableAttr());
+ NewFD->addAttr(::new (Context) OverloadableAttr());
}
// If this is a locally-scoped extern C function, update the
@@ -2797,7 +2795,7 @@ void Sema::ActOnUninitializedDecl(DeclPtrTy dcl) {
InitializeVarWithConstructor(Var, Constructor, InitType, 0, 0);
// FIXME. Must do all that is needed to destroy the object
// on scope exit. For now, just mark the destructor as used.
- MarcDestructorReferenced(Var->getLocation(), InitType);
+ MarkDestructorReferenced(Var->getLocation(), InitType);
}
}
}
@@ -2998,7 +2996,7 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
ProcessDeclAttributes(S, New, D);
- if (New->hasAttr<BlocksAttr>(Context)) {
+ if (New->hasAttr<BlocksAttr>()) {
Diag(New->getLocation(), diag::err_block_on_nonlocal);
}
return DeclPtrTy::make(New);
@@ -3065,7 +3063,7 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
// See if this is a redefinition.
const FunctionDecl *Definition;
- if (FD->getBody(Context, Definition)) {
+ if (FD->getBody(Definition)) {
Diag(FD->getLocation(), diag::err_redefinition) << FD->getDeclName();
Diag(Definition->getLocation(), diag::note_previous_definition);
}
@@ -3128,10 +3126,10 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
// Checking attributes of current function definition
// dllimport attribute.
- if (FD->getAttr<DLLImportAttr>(Context) &&
- (!FD->getAttr<DLLExportAttr>(Context))) {
+ if (FD->getAttr<DLLImportAttr>() &&
+ (!FD->getAttr<DLLExportAttr>())) {
// dllimport attribute cannot be applied to definition.
- if (!(FD->getAttr<DLLImportAttr>(Context))->isInherited()) {
+ if (!(FD->getAttr<DLLImportAttr>())->isInherited()) {
Diag(FD->getLocation(),
diag::err_attribute_can_be_applied_only_to_symbol_declaration)
<< "dllimport";
@@ -3313,9 +3311,8 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
unsigned FormatIdx;
bool HasVAListArg;
if (Context.BuiltinInfo.isPrintfLike(BuiltinID, FormatIdx, HasVAListArg)) {
- if (!FD->getAttr<FormatAttr>(Context))
- FD->addAttr(Context,
- ::new (Context) FormatAttr("printf", FormatIdx + 1,
+ if (!FD->getAttr<FormatAttr>())
+ FD->addAttr(::new (Context) FormatAttr("printf", FormatIdx + 1,
HasVAListArg ? 0 : FormatIdx + 2));
}
@@ -3324,8 +3321,8 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
// IRgen to use LLVM intrinsics for such functions.
if (!getLangOptions().MathErrno &&
Context.BuiltinInfo.isConstWithoutErrno(BuiltinID)) {
- if (!FD->getAttr<ConstAttr>(Context))
- FD->addAttr(Context, ::new (Context) ConstAttr());
+ if (!FD->getAttr<ConstAttr>())
+ FD->addAttr(::new (Context) ConstAttr());
}
}
@@ -3343,17 +3340,15 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
return;
if (Name->isStr("NSLog") || Name->isStr("NSLogv")) {
- if (const FormatAttr *Format = FD->getAttr<FormatAttr>(Context)) {
+ if (const FormatAttr *Format = FD->getAttr<FormatAttr>()) {
// FIXME: We known better than our headers.
const_cast<FormatAttr *>(Format)->setType("printf");
} else
- FD->addAttr(Context,
- ::new (Context) FormatAttr("printf", 1,
+ FD->addAttr(::new (Context) FormatAttr("printf", 1,
Name->isStr("NSLogv") ? 0 : 2));
} else if (Name->isStr("asprintf") || Name->isStr("vasprintf")) {
- if (!FD->getAttr<FormatAttr>(Context))
- FD->addAttr(Context,
- ::new (Context) FormatAttr("printf", 2,
+ if (!FD->getAttr<FormatAttr>())
+ FD->addAttr(::new (Context) FormatAttr("printf", 2,
Name->isStr("vasprintf") ? 0 : 3));
}
}
@@ -3709,7 +3704,7 @@ CreateNewDecl:
// the #pragma tokens are effectively skipped over during the
// parsing of the struct).
if (unsigned Alignment = getPragmaPackAlignment())
- New->addAttr(Context, ::new (Context) PackedAttr(Alignment * 8));
+ New->addAttr(::new (Context) PackedAttr(Alignment * 8));
}
if (getLangOptions().CPlusPlus && SS.isEmpty() && Name && !Invalid) {
@@ -3761,7 +3756,7 @@ CreateNewDecl:
S = getNonFieldDeclScope(S);
PushOnScopeChains(New, S);
} else {
- CurContext->addDecl(Context, New);
+ CurContext->addDecl(New);
}
OwnedDecl = true;
@@ -3917,7 +3912,7 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record,
} else if (II) {
PushOnScopeChains(NewFD, S);
} else
- Record->addDecl(Context, NewFD);
+ Record->addDecl(NewFD);
return NewFD;
}
@@ -4239,7 +4234,7 @@ void Sema::ActOnFields(Scope* S,
// Add ivar's to class's DeclContext.
for (unsigned i = 0, e = RecFields.size(); i != e; ++i) {
ClsFields[i]->setLexicalDeclContext(ID);
- ID->addDecl(Context, ClsFields[i]);
+ ID->addDecl(ClsFields[i]);
}
// Must enforce the rule that ivars in the base classes may not be
// duplicates.
@@ -4250,7 +4245,7 @@ void Sema::ActOnFields(Scope* S,
if (IdentifierInfo *II = Ivar->getIdentifier()) {
ObjCIvarDecl* prevIvar =
- ID->getSuperClass()->lookupInstanceVariable(Context, II);
+ ID->getSuperClass()->lookupInstanceVariable(II);
if (prevIvar) {
Diag(Ivar->getLocation(), diag::err_duplicate_member) << II;
Diag(prevIvar->getLocation(), diag::note_previous_declaration);
@@ -4549,7 +4544,7 @@ Sema::DeclPtrTy Sema::ActOnFileScopeAsmDecl(SourceLocation Loc,
FileScopeAsmDecl *New = FileScopeAsmDecl::Create(Context, CurContext,
Loc, AsmString);
- CurContext->addDecl(Context, New);
+ CurContext->addDecl(New);
return DeclPtrTy::make(New);
}
@@ -4560,7 +4555,7 @@ void Sema::ActOnPragmaWeakID(IdentifierInfo* Name,
// FIXME: This implementation is an ugly hack!
if (PrevDecl) {
- PrevDecl->addAttr(Context, ::new (Context) WeakAttr());
+ PrevDecl->addAttr(::new (Context) WeakAttr());
return;
}
Diag(PragmaLoc, diag::err_unsupported_pragma_weak);
@@ -4576,8 +4571,8 @@ void Sema::ActOnPragmaWeakAlias(IdentifierInfo* Name,
// FIXME: This implementation is an ugly hack!
if (PrevDecl) {
- PrevDecl->addAttr(Context, ::new (Context) AliasAttr(AliasName->getName()));
- PrevDecl->addAttr(Context, ::new (Context) WeakAttr());
+ PrevDecl->addAttr(::new (Context) AliasAttr(AliasName->getName()));
+ PrevDecl->addAttr(::new (Context) WeakAttr());
return;
}
Diag(PragmaLoc, diag::err_unsupported_pragma_weak);
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index f7dd9303cb47..2b71df722459 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -284,7 +284,7 @@ static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
}
if (TagDecl *TD = dyn_cast<TagDecl>(d))
- TD->addAttr(S.Context, ::new (S.Context) PackedAttr(1));
+ TD->addAttr(::new (S.Context) PackedAttr(1));
else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
// If the alignment is less than or equal to 8 bits, the packed attribute
// has no effect.
@@ -293,7 +293,7 @@ static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
<< Attr.getName() << FD->getType();
else
- FD->addAttr(S.Context, ::new (S.Context) PackedAttr(1));
+ FD->addAttr(::new (S.Context) PackedAttr(1));
} else
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
}
@@ -308,7 +308,7 @@ static void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// The IBOutlet attribute only applies to instance variables of Objective-C
// classes.
if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d))
- d->addAttr(S.Context, ::new (S.Context) IBOutletAttr());
+ d->addAttr(::new (S.Context) IBOutletAttr());
else
S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet);
}
@@ -380,7 +380,7 @@ static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
unsigned* start = &NonNullArgs[0];
unsigned size = NonNullArgs.size();
std::sort(start, start + size);
- d->addAttr(S.Context, ::new (S.Context) NonNullAttr(start, size));
+ d->addAttr(::new (S.Context) NonNullAttr(start, size));
}
static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -405,7 +405,7 @@ static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// FIXME: check if target symbol exists in current file
- d->addAttr(S.Context, ::new (S.Context) AliasAttr(std::string(Alias, AliasLen)));
+ d->addAttr(::new (S.Context) AliasAttr(std::string(Alias, AliasLen)));
}
static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
@@ -422,7 +422,7 @@ static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
return;
}
- d->addAttr(S.Context, ::new (S.Context) AlwaysInlineAttr());
+ d->addAttr(::new (S.Context) AlwaysInlineAttr());
}
static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr,
@@ -447,13 +447,13 @@ static bool HandleCommonNoReturnAttr(Decl *d, const AttributeList &Attr,
static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
if (HandleCommonNoReturnAttr(d, Attr, S))
- d->addAttr(S.Context, ::new (S.Context) NoReturnAttr());
+ d->addAttr(::new (S.Context) NoReturnAttr());
}
static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
Sema &S) {
if (HandleCommonNoReturnAttr(d, Attr, S))
- d->addAttr(S.Context, ::new (S.Context) AnalyzerNoReturnAttr());
+ d->addAttr(::new (S.Context) AnalyzerNoReturnAttr());
}
static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -469,7 +469,7 @@ static void HandleUnusedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) UnusedAttr());
+ d->addAttr(::new (S.Context) UnusedAttr());
}
static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -490,7 +490,7 @@ static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) UsedAttr());
+ d->addAttr(::new (S.Context) UsedAttr());
}
static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -519,7 +519,7 @@ static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) ConstructorAttr(priority));
+ d->addAttr(::new (S.Context) ConstructorAttr(priority));
}
static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -548,7 +548,7 @@ static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) DestructorAttr(priority));
+ d->addAttr(::new (S.Context) DestructorAttr(priority));
}
static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -558,7 +558,7 @@ static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) DeprecatedAttr());
+ d->addAttr(::new (S.Context) DeprecatedAttr());
}
static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -568,7 +568,7 @@ static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) UnavailableAttr());
+ d->addAttr(::new (S.Context) UnavailableAttr());
}
static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -605,7 +605,7 @@ static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) VisibilityAttr(type));
+ d->addAttr(::new (S.Context) VisibilityAttr(type));
}
static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
@@ -621,7 +621,7 @@ static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
return;
}
- D->addAttr(S.Context, ::new (S.Context) ObjCExceptionAttr());
+ D->addAttr(::new (S.Context) ObjCExceptionAttr());
}
static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -637,7 +637,7 @@ static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
return;
}
}
- D->addAttr(S.Context, ::new (S.Context) ObjCNSObjectAttr());
+ D->addAttr(::new (S.Context) ObjCNSObjectAttr());
}
static void
@@ -652,7 +652,7 @@ HandleOverloadableAttr(Decl *D, const AttributeList &Attr, Sema &S) {
return;
}
- D->addAttr(S.Context, ::new (S.Context) OverloadableAttr());
+ D->addAttr(::new (S.Context) OverloadableAttr());
}
static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -676,7 +676,7 @@ static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) BlocksAttr(type));
+ d->addAttr(::new (S.Context) BlocksAttr(type));
}
static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -768,7 +768,7 @@ static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
<< Attr.getName() << 6 /*function, method or block */;
return;
}
- d->addAttr(S.Context, ::new (S.Context) SentinelAttr(sentinel, nullPos));
+ d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos));
}
static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -786,7 +786,7 @@ static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S)
return;
}
- Fn->addAttr(S.Context, ::new (S.Context) WarnUnusedResultAttr());
+ Fn->addAttr(::new (S.Context) WarnUnusedResultAttr());
}
static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -803,7 +803,7 @@ static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
return;
}
- D->addAttr(S.Context, ::new (S.Context) WeakAttr());
+ D->addAttr(::new (S.Context) WeakAttr());
}
static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -818,7 +818,7 @@ static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
isDef = (!VD->hasExternalStorage() || VD->getInit());
} else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
- isDef = FD->getBody(S.Context);
+ isDef = FD->getBody();
} else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D)) {
// We ignore weak import on properties and methods
return;
@@ -836,7 +836,7 @@ static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
return;
}
- D->addAttr(S.Context, ::new (S.Context) WeakImportAttr());
+ D->addAttr(::new (S.Context) WeakImportAttr());
}
static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -848,7 +848,7 @@ static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
// Attribute can be applied only to functions or variables.
if (isa<VarDecl>(D)) {
- D->addAttr(S.Context, ::new (S.Context) DLLImportAttr());
+ D->addAttr(::new (S.Context) DLLImportAttr());
return;
}
@@ -876,12 +876,12 @@ static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
}
}
- if (D->getAttr<DLLExportAttr>(S.Context)) {
+ if (D->getAttr<DLLExportAttr>()) {
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "dllimport";
return;
}
- D->addAttr(S.Context, ::new (S.Context) DLLImportAttr());
+ D->addAttr(::new (S.Context) DLLImportAttr());
}
static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -893,7 +893,7 @@ static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
// Attribute can be applied only to functions or variables.
if (isa<VarDecl>(D)) {
- D->addAttr(S.Context, ::new (S.Context) DLLExportAttr());
+ D->addAttr(::new (S.Context) DLLExportAttr());
return;
}
@@ -912,7 +912,7 @@ static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
return;
}
- D->addAttr(S.Context, ::new (S.Context) DLLExportAttr());
+ D->addAttr(::new (S.Context) DLLExportAttr());
}
static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
@@ -934,8 +934,7 @@ static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
}
WGSize[i] = (unsigned) ArgNum.getZExtValue();
}
- D->addAttr(S.Context,
- ::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1],
+ D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1],
WGSize[2]));
}
@@ -955,8 +954,7 @@ static void HandleSectionAttr(Decl *D, const AttributeList &Attr, Sema &S) {
S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
return;
}
- D->addAttr(S.Context,
- ::new (S.Context) SectionAttr(std::string(SE->getStrData(),
+ D->addAttr(::new (S.Context) SectionAttr(std::string(SE->getStrData(),
SE->getByteLength())));
}
@@ -975,13 +973,13 @@ static void HandleStdCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
}
// stdcall and fastcall attributes are mutually incompatible.
- if (d->getAttr<FastCallAttr>(S.Context)) {
+ if (d->getAttr<FastCallAttr>()) {
S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
<< "stdcall" << "fastcall";
return;
}
- d->addAttr(S.Context, ::new (S.Context) StdCallAttr());
+ d->addAttr(::new (S.Context) StdCallAttr());
}
static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -998,13 +996,13 @@ static void HandleFastCallAttr(Decl *d, const AttributeList &Attr, Sema &S) {
}
// stdcall and fastcall attributes are mutually incompatible.
- if (d->getAttr<StdCallAttr>(S.Context)) {
+ if (d->getAttr<StdCallAttr>()) {
S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)
<< "fastcall" << "stdcall";
return;
}
- d->addAttr(S.Context, ::new (S.Context) FastCallAttr());
+ d->addAttr(::new (S.Context) FastCallAttr());
}
static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1014,7 +1012,7 @@ static void HandleNothrowAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) NoThrowAttr());
+ d->addAttr(::new (S.Context) NoThrowAttr());
}
static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1024,7 +1022,7 @@ static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) ConstAttr());
+ d->addAttr(::new (S.Context) ConstAttr());
}
static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1034,7 +1032,7 @@ static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) PureAttr());
+ d->addAttr(::new (S.Context) PureAttr());
}
static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1092,7 +1090,7 @@ static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) CleanupAttr(FD));
+ d->addAttr(::new (S.Context) CleanupAttr(FD));
}
/// Handle __attribute__((format_arg((idx)))) attribute
@@ -1155,7 +1153,7 @@ static void HandleFormatArgAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) FormatArgAttr(Idx.getZExtValue()));
+ d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue()));
}
/// Handle __attribute__((format(type,idx,firstarg))) attributes
@@ -1296,8 +1294,7 @@ static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context,
- ::new (S.Context) FormatAttr(std::string(Format, FormatLen),
+ d->addAttr(::new (S.Context) FormatAttr(std::string(Format, FormatLen),
Idx.getZExtValue(), FirstArg.getZExtValue()));
}
@@ -1329,8 +1326,8 @@ static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
return;
}
- RecordDecl::field_iterator Field = RD->field_begin(S.Context),
- FieldEnd = RD->field_end(S.Context);
+ RecordDecl::field_iterator Field = RD->field_begin(),
+ FieldEnd = RD->field_end();
if (Field == FieldEnd) {
S.Diag(Attr.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
return;
@@ -1365,7 +1362,7 @@ static void HandleTransparentUnionAttr(Decl *d, const AttributeList &Attr,
}
}
- RD->addAttr(S.Context, ::new (S.Context) TransparentUnionAttr());
+ RD->addAttr(::new (S.Context) TransparentUnionAttr());
}
static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1383,8 +1380,7 @@ static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
S.Diag(Attr.getLoc(), diag::err_attribute_annotate_no_string);
return;
}
- d->addAttr(S.Context,
- ::new (S.Context) AnnotateAttr(std::string(SE->getStrData(),
+ d->addAttr(::new (S.Context) AnnotateAttr(std::string(SE->getStrData(),
SE->getByteLength())));
}
@@ -1400,7 +1396,7 @@ static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// FIXME: This should be the target specific maximum alignment.
// (For now we just use 128 bits which is the maximum on X86).
Align = 128;
- d->addAttr(S.Context, ::new (S.Context) AlignedAttr(Align));
+ d->addAttr(::new (S.Context) AlignedAttr(Align));
return;
}
@@ -1417,7 +1413,7 @@ static void HandleAlignedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8));
+ d->addAttr(::new (S.Context) AlignedAttr(Alignment.getZExtValue() * 8));
}
/// HandleModeAttr - This attribute modifies the width of a decl with
@@ -1598,7 +1594,7 @@ static void HandleNodebugAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) NodebugAttr());
+ d->addAttr(::new (S.Context) NodebugAttr());
}
static void HandleNoinlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1614,7 +1610,7 @@ static void HandleNoinlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) NoinlineAttr());
+ d->addAttr(::new (S.Context) NoinlineAttr());
}
static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1636,7 +1632,7 @@ static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context, ::new (S.Context) GNUInlineAttr());
+ d->addAttr(::new (S.Context) GNUInlineAttr());
}
static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1672,8 +1668,7 @@ static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
return;
}
- d->addAttr(S.Context,
- ::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
+ d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
}
//===----------------------------------------------------------------------===//
@@ -1706,10 +1701,10 @@ static void HandleNSReturnsRetainedAttr(Decl *d, const AttributeList &Attr,
assert(0 && "invalid ownership attribute");
return;
case AttributeList::AT_cf_returns_retained:
- d->addAttr(S.Context, ::new (S.Context) CFReturnsRetainedAttr());
+ d->addAttr(::new (S.Context) CFReturnsRetainedAttr());
return;
case AttributeList::AT_ns_returns_retained:
- d->addAttr(S.Context, ::new (S.Context) NSReturnsRetainedAttr());
+ d->addAttr(::new (S.Context) NSReturnsRetainedAttr());
return;
};
}
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index cf0dab5cf298..75ceb1916555 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -258,6 +258,12 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old) {
}
}
+ if (CheckEquivalentExceptionSpec(
+ Old->getType()->getAsFunctionProtoType(), Old->getLocation(),
+ New->getType()->getAsFunctionProtoType(), New->getLocation())) {
+ Invalid = true;
+ }
+
return Invalid;
}
@@ -481,7 +487,7 @@ bool Sema::AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases,
}
// Attach the remaining base class specifiers to the derived class.
- Class->setBases(Bases, NumGoodBases);
+ Class->setBases(Context, Bases, NumGoodBases);
// Delete the remaining (good) base class specifiers, since their
// data has been copied into the CXXRecordDecl.
@@ -646,7 +652,9 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
Sema::MemInitResult
Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
Scope *S,
+ const CXXScopeSpec &SS,
IdentifierInfo *MemberOrBase,
+ TypeTy *TemplateTypeTy,
SourceLocation IdLoc,
SourceLocation LParenLoc,
ExprTy **Args, unsigned NumArgs,
@@ -677,28 +685,31 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
// composed of a single identifier refers to the class member. A
// mem-initializer-id for the hidden base class may be specified
// using a qualified name. ]
- // Look for a member, first.
- FieldDecl *Member = 0;
- DeclContext::lookup_result Result
- = ClassDecl->lookup(Context, MemberOrBase);
- if (Result.first != Result.second)
- Member = dyn_cast<FieldDecl>(*Result.first);
-
- // FIXME: Handle members of an anonymous union.
-
- if (Member) {
- // FIXME: Perform direct initialization of the member.
- return new CXXBaseOrMemberInitializer(Member, (Expr **)Args, NumArgs);
+ if (!SS.getScopeRep() && !TemplateTypeTy) {
+ // Look for a member, first.
+ FieldDecl *Member = 0;
+ DeclContext::lookup_result Result
+ = ClassDecl->lookup(MemberOrBase);
+ if (Result.first != Result.second)
+ Member = dyn_cast<FieldDecl>(*Result.first);
+
+ // FIXME: Handle members of an anonymous union.
+
+ if (Member) {
+ // FIXME: Perform direct initialization of the member.
+ return new CXXBaseOrMemberInitializer(Member, (Expr **)Args, NumArgs,
+ IdLoc);
+ }
}
-
// It didn't name a member, so see if it names a class.
- TypeTy *BaseTy = getTypeName(*MemberOrBase, IdLoc, S, 0/*SS*/);
+ TypeTy *BaseTy = TemplateTypeTy ? TemplateTypeTy
+ : getTypeName(*MemberOrBase, IdLoc, S, &SS);
if (!BaseTy)
return Diag(IdLoc, diag::err_mem_init_not_member_or_class)
<< MemberOrBase << SourceRange(IdLoc, RParenLoc);
QualType BaseType = QualType::getFromOpaquePtr(BaseTy);
- if (!BaseType->isRecordType())
+ if (!BaseType->isRecordType() && !BaseType->isDependentType())
return Diag(IdLoc, diag::err_base_init_does_not_name_class)
<< BaseType << SourceRange(IdLoc, RParenLoc);
@@ -749,8 +760,18 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD,
if (DirectBaseSpec && VirtualBaseSpec)
return Diag(IdLoc, diag::err_base_init_direct_and_virtual)
<< MemberOrBase << SourceRange(IdLoc, RParenLoc);
+ // C++ [base.class.init]p2:
+ // Unless the mem-initializer-id names a nonstatic data membeer of the
+ // constructor's class ot a direst or virtual base of that class, the
+ // mem-initializer is ill-formed.
+ if (!DirectBaseSpec && !VirtualBaseSpec)
+ return Diag(IdLoc, diag::err_not_direct_base_or_virtual)
+ << BaseType << ClassDecl->getNameAsCString()
+ << SourceRange(IdLoc, RParenLoc);
+
- return new CXXBaseOrMemberInitializer(BaseType, (Expr **)Args, NumArgs);
+ return new CXXBaseOrMemberInitializer(BaseType, (Expr **)Args, NumArgs,
+ IdLoc);
}
void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl,
@@ -766,6 +787,42 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl,
Diag(ColonLoc, diag::err_only_constructors_take_base_inits);
return;
}
+ llvm::DenseMap<void*, CXXBaseOrMemberInitializer *>Members;
+ bool err = false;
+ for (unsigned i = 0; i < NumMemInits; i++) {
+ CXXBaseOrMemberInitializer *Member =
+ static_cast<CXXBaseOrMemberInitializer*>(MemInits[i]);
+ void *KeyToMember = Member->getBaseOrMember();
+ // For fields injected into the class via declaration of an anonymous union,
+ // use its anonymous union class declaration as the unique key.
+ if (FieldDecl *Field = Member->getMember())
+ if (Field->getDeclContext()->isRecord() &&
+ cast<RecordDecl>(Field->getDeclContext())->isAnonymousStructOrUnion())
+ KeyToMember = static_cast<void *>(Field->getDeclContext());
+ CXXBaseOrMemberInitializer *&PrevMember = Members[KeyToMember];
+ if (!PrevMember) {
+ PrevMember = Member;
+ continue;
+ }
+ if (FieldDecl *Field = Member->getMember())
+ Diag(Member->getSourceLocation(),
+ diag::error_multiple_mem_initialization)
+ << Field->getNameAsString();
+ else {
+ Type *BaseClass = Member->getBaseClass();
+ assert(BaseClass && "ActOnMemInitializers - neither field or base");
+ Diag(Member->getSourceLocation(),
+ diag::error_multiple_base_initialization)
+ << BaseClass->getDesugaredType(true);
+ }
+ Diag(PrevMember->getSourceLocation(), diag::note_previous_initializer)
+ << 0;
+ err = true;
+ }
+ if (!err)
+ Constructor->setBaseOrMemberInitializers(Context,
+ reinterpret_cast<CXXBaseOrMemberInitializer **>(MemInits),
+ NumMemInits);
}
namespace {
@@ -821,8 +878,7 @@ namespace {
MethodSetTy OverriddenMethods;
size_t MethodsSize = Methods.size();
- for (RecordDecl::decl_iterator i = RD->decls_begin(Context),
- e = RD->decls_end(Context);
+ for (RecordDecl::decl_iterator i = RD->decls_begin(), e = RD->decls_end();
i != e; ++i) {
// Traverse the record, looking for methods.
if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(*i)) {
@@ -919,8 +975,8 @@ namespace {
bool VisitDeclContext(const DeclContext *DC) {
bool Invalid = false;
- for (CXXRecordDecl::decl_iterator I = DC->decls_begin(SemaRef.Context),
- E = DC->decls_end(SemaRef.Context); I != E; ++I)
+ for (CXXRecordDecl::decl_iterator I = DC->decls_begin(),
+ E = DC->decls_end(); I != E; ++I)
Invalid |= Visit(*I);
return Invalid;
@@ -996,8 +1052,8 @@ void Sema::ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
AbstractClassUsageDiagnoser(*this, RD);
if (RD->hasTrivialConstructor() || RD->hasTrivialDestructor()) {
- for (RecordDecl::field_iterator i = RD->field_begin(Context),
- e = RD->field_end(Context); i != e; ++i) {
+ for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
+ i != e; ++i) {
// All the nonstatic data members must have trivial constructors.
QualType FTy = i->getType();
while (const ArrayType *AT = Context.getAsArrayType(FTy))
@@ -1054,7 +1110,7 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
/*isImplicitlyDeclared=*/true);
DefaultCon->setAccess(AS_public);
DefaultCon->setImplicit();
- ClassDecl->addDecl(Context, DefaultCon);
+ ClassDecl->addDecl(DefaultCon);
}
if (!ClassDecl->hasUserDeclaredCopyConstructor()) {
@@ -1086,8 +1142,8 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
// class type M (or array thereof), each such class type
// has a copy constructor whose first parameter is of type
// const M& or const volatile M&.
- for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(Context);
- HasConstCopyConstructor && Field != ClassDecl->field_end(Context);
+ for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin();
+ HasConstCopyConstructor && Field != ClassDecl->field_end();
++Field) {
QualType FieldType = (*Field)->getType();
if (const ArrayType *Array = Context.getAsArrayType(FieldType))
@@ -1131,7 +1187,7 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
/*IdentifierInfo=*/0,
ArgType, VarDecl::None, 0);
CopyConstructor->setParams(Context, &FromParam, 1);
- ClassDecl->addDecl(Context, CopyConstructor);
+ ClassDecl->addDecl(CopyConstructor);
}
if (!ClassDecl->hasUserDeclaredCopyAssignment()) {
@@ -1165,8 +1221,8 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
// type M (or array thereof), each such class type has a copy
// assignment operator whose parameter is of type const M&,
// const volatile M& or M.
- for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(Context);
- HasConstCopyAssignment && Field != ClassDecl->field_end(Context);
+ for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin();
+ HasConstCopyAssignment && Field != ClassDecl->field_end();
++Field) {
QualType FieldType = (*Field)->getType();
if (const ArrayType *Array = Context.getAsArrayType(FieldType))
@@ -1210,7 +1266,7 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
// Don't call addedAssignmentOperator. There is no way to distinguish an
// implicit from an explicit assignment operator.
- ClassDecl->addDecl(Context, CopyAssignment);
+ ClassDecl->addDecl(CopyAssignment);
}
if (!ClassDecl->hasUserDeclaredDestructor()) {
@@ -1229,7 +1285,7 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
/*isImplicitlyDeclared=*/true);
Destructor->setAccess(AS_public);
Destructor->setImplicit();
- ClassDecl->addDecl(Context, Destructor);
+ ClassDecl->addDecl(Destructor);
}
}
@@ -1772,7 +1828,7 @@ void Sema::PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir) {
// or translation unit scope. We add UsingDirectiveDecls, into
// it's lookup structure.
if (DeclContext *Ctx = static_cast<DeclContext*>(S->getEntity()))
- Ctx->addDecl(Context, UDir);
+ Ctx->addDecl(UDir);
else
// Otherwise it is block-sope. using-directives will affect lookup
// only to the end of scope.
@@ -1873,7 +1929,7 @@ Sema::DeclPtrTy Sema::ActOnNamespaceAliasDef(Scope *S,
(NestedNameSpecifier *)SS.getScopeRep(),
IdentLoc, R);
- CurContext->addDecl(Context, AliasDecl);
+ CurContext->addDecl(AliasDecl);
return DeclPtrTy::make(AliasDecl);
}
@@ -1891,8 +1947,8 @@ void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
// for its base class and its non-static data members shall have been
// implicitly defined.
bool err = false;
- for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin();
- Base != ClassDecl->bases_end(); ++Base) {
+ for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
+ E = ClassDecl->bases_end(); Base != E; ++Base) {
CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(Base->getType()->getAsRecordType()->getDecl());
if (!BaseClassDecl->hasTrivialConstructor()) {
@@ -1909,9 +1965,8 @@ void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation,
}
}
}
- for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(Context);
- Field != ClassDecl->field_end(Context);
- ++Field) {
+ for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+ E = ClassDecl->field_end(); Field != E; ++Field) {
QualType FieldType = Context.getCanonicalType((*Field)->getType());
if (const ArrayType *Array = Context.getAsArrayType(FieldType))
FieldType = Array->getElementType();
@@ -1964,8 +2019,8 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
// implicitly defined, all the implicitly-declared default destructors
// for its base class and its non-static data members shall have been
// implicitly defined.
- for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin();
- Base != ClassDecl->bases_end(); ++Base) {
+ for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
+ E = ClassDecl->bases_end(); Base != E; ++Base) {
CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(Base->getType()->getAsRecordType()->getDecl());
if (!BaseClassDecl->hasTrivialDestructor()) {
@@ -1978,9 +2033,8 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
}
}
- for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(Context);
- Field != ClassDecl->field_end(Context);
- ++Field) {
+ for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+ E = ClassDecl->field_end(); Field != E; ++Field) {
QualType FieldType = Context.getCanonicalType((*Field)->getType());
if (const ArrayType *Array = Context.getAsArrayType(FieldType))
FieldType = Array->getElementType();
@@ -2010,7 +2064,6 @@ void Sema::DefineImplicitOverloadedAssign(SourceLocation CurrentLocation,
CXXRecordDecl *ClassDecl
= cast<CXXRecordDecl>(MethodDecl->getDeclContext());
- assert(ClassDecl && "DefineImplicitOverloadedAssign - invalid constructor");
// C++[class.copy] p12
// Before the implicitly-declared copy assignment operator for a class is
@@ -2018,17 +2071,16 @@ void Sema::DefineImplicitOverloadedAssign(SourceLocation CurrentLocation,
// for its direct base classes and its nonstatic data members shall have
// been implicitly defined.
bool err = false;
- for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin();
- Base != ClassDecl->bases_end(); ++Base) {
+ for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
+ E = ClassDecl->bases_end(); Base != E; ++Base) {
CXXRecordDecl *BaseClassDecl
= cast<CXXRecordDecl>(Base->getType()->getAsRecordType()->getDecl());
if (CXXMethodDecl *BaseAssignOpMethod =
getAssignOperatorMethod(MethodDecl->getParamDecl(0), BaseClassDecl))
MarkDeclarationReferenced(CurrentLocation, BaseAssignOpMethod);
}
- for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(Context);
- Field != ClassDecl->field_end(Context);
- ++Field) {
+ for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+ E = ClassDecl->field_end(); Field != E; ++Field) {
QualType FieldType = Context.getCanonicalType((*Field)->getType());
if (const ArrayType *Array = Context.getAsArrayType(FieldType))
FieldType = Array->getElementType();
@@ -2113,9 +2165,9 @@ void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation,
BaseClassDecl->getCopyConstructor(Context, TypeQuals))
MarkDeclarationReferenced(CurrentLocation, BaseCopyCtor);
}
- for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(Context);
- Field != ClassDecl->field_end(Context);
- ++Field) {
+ for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+ FieldEnd = ClassDecl->field_end();
+ Field != FieldEnd; ++Field) {
QualType FieldType = Context.getCanonicalType((*Field)->getType());
if (const ArrayType *Array = Context.getAsArrayType(FieldType))
FieldType = Array->getElementType();
@@ -2140,7 +2192,7 @@ void Sema::InitializeVarWithConstructor(VarDecl *VD,
VD->setInit(Context, Temp);
}
-void Sema::MarcDestructorReferenced(SourceLocation Loc, QualType DeclInitType)
+void Sema::MarkDestructorReferenced(SourceLocation Loc, QualType DeclInitType)
{
CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(
DeclInitType->getAsRecordType()->getDecl());
@@ -2218,7 +2270,7 @@ void Sema::AddCXXDirectInitializerToDecl(DeclPtrTy Dcl,
(Expr**)Exprs.release(), NumExprs);
// FIXME. Must do all that is needed to destroy the object
// on scope exit. For now, just mark the destructor as used.
- MarcDestructorReferenced(VDecl->getLocation(), DeclInitType);
+ MarkDestructorReferenced(VDecl->getLocation(), DeclInitType);
}
return;
}
@@ -2282,7 +2334,7 @@ Sema::PerformInitializationByConstructor(QualType ClassType,
= Context.DeclarationNames.getCXXConstructorName(
Context.getCanonicalType(ClassType.getUnqualifiedType()));
DeclContext::lookup_const_iterator Con, ConEnd;
- for (llvm::tie(Con, ConEnd) = ClassDecl->lookup(Context, ConstructorName);
+ for (llvm::tie(Con, ConEnd) = ClassDecl->lookup(ConstructorName);
Con != ConEnd; ++Con) {
CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
if ((Kind == IK_Direct) ||
@@ -2892,7 +2944,7 @@ Sema::DeclPtrTy Sema::ActOnStartLinkageSpecification(Scope *S,
LinkageSpecDecl *D = LinkageSpecDecl::Create(Context, CurContext,
LangLoc, Language,
LBraceLoc.isValid());
- CurContext->addDecl(Context, D);
+ CurContext->addDecl(D);
PushDeclContext(S, D);
return DeclPtrTy::make(D);
}
@@ -3006,7 +3058,7 @@ Sema::DeclPtrTy Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) {
if (II)
PushOnScopeChains(ExDecl, S);
else
- CurContext->addDecl(Context, ExDecl);
+ CurContext->addDecl(ExDecl);
ProcessDeclAttributes(S, ExDecl, D);
return DeclPtrTy::make(ExDecl);
@@ -3040,7 +3092,7 @@ Sema::DeclPtrTy Sema::ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
Decl *Decl = StaticAssertDecl::Create(Context, CurContext, AssertLoc,
AssertExpr, AssertMessage);
- CurContext->addDecl(Context, Decl);
+ CurContext->addDecl(Decl);
return DeclPtrTy::make(Decl);
}
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 9013726e1aee..5cf48d6da0c8 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -379,12 +379,12 @@ void Sema::ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl) {
if (!SDecl)
return;
// FIXME: O(N^2)
- for (ObjCInterfaceDecl::prop_iterator S = SDecl->prop_begin(Context),
- E = SDecl->prop_end(Context); S != E; ++S) {
+ for (ObjCInterfaceDecl::prop_iterator S = SDecl->prop_begin(),
+ E = SDecl->prop_end(); S != E; ++S) {
ObjCPropertyDecl *SuperPDecl = (*S);
// Does property in super class has declaration in current class?
- for (ObjCInterfaceDecl::prop_iterator I = IDecl->prop_begin(Context),
- E = IDecl->prop_end(Context); I != E; ++I) {
+ for (ObjCInterfaceDecl::prop_iterator I = IDecl->prop_begin(),
+ E = IDecl->prop_end(); I != E; ++I) {
ObjCPropertyDecl *PDecl = (*I);
if (SuperPDecl->getIdentifier() == PDecl->getIdentifier())
DiagnosePropertyMismatch(PDecl, SuperPDecl,
@@ -404,13 +404,12 @@ Sema::MergeOneProtocolPropertiesIntoClass(Decl *CDecl,
// Category
ObjCCategoryDecl *CatDecl = static_cast<ObjCCategoryDecl*>(CDecl);
assert (CatDecl && "MergeOneProtocolPropertiesIntoClass");
- for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(Context),
- E = PDecl->prop_end(Context); P != E; ++P) {
+ for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
+ E = PDecl->prop_end(); P != E; ++P) {
ObjCPropertyDecl *Pr = (*P);
ObjCCategoryDecl::prop_iterator CP, CE;
// Is this property already in category's list of properties?
- for (CP = CatDecl->prop_begin(Context), CE = CatDecl->prop_end(Context);
- CP != CE; ++CP)
+ for (CP = CatDecl->prop_begin(), CE = CatDecl->prop_end(); CP != CE; ++CP)
if ((*CP)->getIdentifier() == Pr->getIdentifier())
break;
if (CP != CE)
@@ -419,13 +418,12 @@ Sema::MergeOneProtocolPropertiesIntoClass(Decl *CDecl,
}
return;
}
- for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(Context),
- E = PDecl->prop_end(Context); P != E; ++P) {
+ for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
+ E = PDecl->prop_end(); P != E; ++P) {
ObjCPropertyDecl *Pr = (*P);
ObjCInterfaceDecl::prop_iterator CP, CE;
// Is this property already in class's list of properties?
- for (CP = IDecl->prop_begin(Context), CE = IDecl->prop_end(Context);
- CP != CE; ++CP)
+ for (CP = IDecl->prop_begin(), CE = IDecl->prop_end(); CP != CE; ++CP)
if ((*CP)->getIdentifier() == Pr->getIdentifier())
break;
if (CP != CE)
@@ -495,16 +493,16 @@ void Sema::DiagnoseClassExtensionDupMethods(ObjCCategoryDecl *CAT,
return; // Possibly due to previous error
llvm::DenseMap<Selector, const ObjCMethodDecl*> MethodMap;
- for (ObjCInterfaceDecl::method_iterator i = ID->meth_begin(Context),
- e = ID->meth_end(Context); i != e; ++i) {
+ for (ObjCInterfaceDecl::method_iterator i = ID->meth_begin(),
+ e = ID->meth_end(); i != e; ++i) {
ObjCMethodDecl *MD = *i;
MethodMap[MD->getSelector()] = MD;
}
if (MethodMap.empty())
return;
- for (ObjCCategoryDecl::method_iterator i = CAT->meth_begin(Context),
- e = CAT->meth_end(Context); i != e; ++i) {
+ for (ObjCCategoryDecl::method_iterator i = CAT->meth_begin(),
+ e = CAT->meth_end(); i != e; ++i) {
ObjCMethodDecl *Method = *i;
const ObjCMethodDecl *&PrevMethod = MethodMap[Method->getSelector()];
if (PrevMethod && !MatchTwoMethodDeclarations(Method, PrevMethod)) {
@@ -539,7 +537,7 @@ Sema::ActOnForwardProtocolDeclaration(SourceLocation AtProtocolLoc,
ObjCForwardProtocolDecl *PDecl =
ObjCForwardProtocolDecl::Create(Context, CurContext, AtProtocolLoc,
&Protocols[0], Protocols.size());
- CurContext->addDecl(Context, PDecl);
+ CurContext->addDecl(PDecl);
CheckObjCDeclScope(PDecl);
return DeclPtrTy::make(PDecl);
}
@@ -555,7 +553,7 @@ ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc,
ObjCCategoryDecl *CDecl =
ObjCCategoryDecl::Create(Context, CurContext, AtInterfaceLoc, CategoryName);
// FIXME: PushOnScopeChains?
- CurContext->addDecl(Context, CDecl);
+ CurContext->addDecl(CDecl);
ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName);
/// Check that class of this category is already completely declared.
@@ -609,7 +607,7 @@ Sema::DeclPtrTy Sema::ActOnStartCategoryImplementation(
Diag(ClassLoc, diag::err_undef_interface) << ClassName;
// FIXME: PushOnScopeChains?
- CurContext->addDecl(Context, CDecl);
+ CurContext->addDecl(CDecl);
/// TODO: Check that CatName, category name, is not used in another
// implementation.
@@ -808,7 +806,7 @@ bool Sema::isPropertyReadonly(ObjCPropertyDecl *PDecl,
return false;
// Even if property is ready only, if interface has a user defined setter,
// it is not considered read only.
- if (IDecl->getInstanceMethod(Context, PDecl->getSetterName()))
+ if (IDecl->getInstanceMethod(PDecl->getSetterName()))
return false;
// Main class has the property as 'readonly'. Must search
@@ -818,10 +816,10 @@ bool Sema::isPropertyReadonly(ObjCPropertyDecl *PDecl,
Category; Category = Category->getNextClassCategory()) {
// Even if property is ready only, if a category has a user defined setter,
// it is not considered read only.
- if (Category->getInstanceMethod(Context, PDecl->getSetterName()))
+ if (Category->getInstanceMethod(PDecl->getSetterName()))
return false;
ObjCPropertyDecl *P =
- Category->FindPropertyDeclaration(Context, PDecl->getIdentifier());
+ Category->FindPropertyDeclaration(PDecl->getIdentifier());
if (P && !P->isReadOnly())
return false;
}
@@ -831,19 +829,19 @@ bool Sema::isPropertyReadonly(ObjCPropertyDecl *PDecl,
if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(CurContext)) {
if (ObjCImplementationDecl *IMD =
dyn_cast<ObjCImplementationDecl>(OMD->getDeclContext())) {
- if (IMD->getInstanceMethod(Context, PDecl->getSetterName()))
+ if (IMD->getInstanceMethod(PDecl->getSetterName()))
return false;
}
else if (ObjCCategoryImplDecl *CIMD =
dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) {
- if (CIMD->getInstanceMethod(Context, PDecl->getSetterName()))
+ if (CIMD->getInstanceMethod(PDecl->getSetterName()))
return false;
}
}
// Lastly, look through the implementation (if one is in scope).
if (ObjCImplementationDecl *ImpDecl
= LookupObjCImplementation(IDecl->getIdentifier()))
- if (ImpDecl->getInstanceMethod(Context, PDecl->getSetterName()))
+ if (ImpDecl->getInstanceMethod(PDecl->getSetterName()))
return false;
// If all fails, look at the super class.
if (ObjCInterfaceDecl *SIDecl = IDecl->getSuperClass())
@@ -890,31 +888,30 @@ void Sema::CheckProtocolMethodDefs(SourceLocation ImpLoc,
// check unimplemented instance methods.
if (!NSIDecl)
- for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(Context),
- E = PDecl->instmeth_end(Context); I != E; ++I) {
+ for (ObjCProtocolDecl::instmeth_iterator I = PDecl->instmeth_begin(),
+ E = PDecl->instmeth_end(); I != E; ++I) {
ObjCMethodDecl *method = *I;
if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
!method->isSynthesized() && !InsMap.count(method->getSelector()) &&
(!Super ||
- !Super->lookupInstanceMethod(Context, method->getSelector()))) {
+ !Super->lookupInstanceMethod(method->getSelector()))) {
// Ugly, but necessary. Method declared in protcol might have
// have been synthesized due to a property declared in the class which
// uses the protocol.
ObjCMethodDecl *MethodInClass =
- IDecl->lookupInstanceMethod(Context, method->getSelector());
+ IDecl->lookupInstanceMethod(method->getSelector());
if (!MethodInClass || !MethodInClass->isSynthesized())
WarnUndefinedMethod(ImpLoc, method, IncompleteImpl);
}
}
// check unimplemented class methods
for (ObjCProtocolDecl::classmeth_iterator
- I = PDecl->classmeth_begin(Context),
- E = PDecl->classmeth_end(Context);
+ I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
I != E; ++I) {
ObjCMethodDecl *method = *I;
if (method->getImplementationControl() != ObjCMethodDecl::Optional &&
!ClsMap.count(method->getSelector()) &&
- (!Super || !Super->lookupClassMethod(Context, method->getSelector())))
+ (!Super || !Super->lookupClassMethod(method->getSelector())))
WarnUndefinedMethod(ImpLoc, method, IncompleteImpl);
}
// Check on this protocols's referenced protocols, recursively.
@@ -937,8 +934,8 @@ void Sema::MatchAllMethodDeclarations(const llvm::DenseSet<Selector> &InsMap,
{
// Check and see if instance methods in class interface have been
// implemented in the implementation class. If so, their types match.
- for (ObjCInterfaceDecl::instmeth_iterator I = CDecl->instmeth_begin(Context),
- E = CDecl->instmeth_end(Context); I != E; ++I) {
+ for (ObjCInterfaceDecl::instmeth_iterator I = CDecl->instmeth_begin(),
+ E = CDecl->instmeth_end(); I != E; ++I) {
if (InsMapSeen.count((*I)->getSelector()))
continue;
InsMapSeen.insert((*I)->getSelector());
@@ -950,9 +947,9 @@ void Sema::MatchAllMethodDeclarations(const llvm::DenseSet<Selector> &InsMap,
}
else {
ObjCMethodDecl *ImpMethodDecl =
- IMPDecl->getInstanceMethod(Context, (*I)->getSelector());
+ IMPDecl->getInstanceMethod((*I)->getSelector());
ObjCMethodDecl *IntfMethodDecl =
- CDecl->getInstanceMethod(Context, (*I)->getSelector());
+ CDecl->getInstanceMethod((*I)->getSelector());
assert(IntfMethodDecl &&
"IntfMethodDecl is null in ImplMethodsVsClassMethods");
// ImpMethodDecl may be null as in a @dynamic property.
@@ -964,9 +961,7 @@ void Sema::MatchAllMethodDeclarations(const llvm::DenseSet<Selector> &InsMap,
// Check and see if class methods in class interface have been
// implemented in the implementation class. If so, their types match.
for (ObjCInterfaceDecl::classmeth_iterator
- I = CDecl->classmeth_begin(Context),
- E = CDecl->classmeth_end(Context);
- I != E; ++I) {
+ I = CDecl->classmeth_begin(), E = CDecl->classmeth_end(); I != E; ++I) {
if (ClsMapSeen.count((*I)->getSelector()))
continue;
ClsMapSeen.insert((*I)->getSelector());
@@ -975,10 +970,10 @@ void Sema::MatchAllMethodDeclarations(const llvm::DenseSet<Selector> &InsMap,
WarnUndefinedMethod(IMPDecl->getLocation(), *I, IncompleteImpl);
}
else {
- ObjCMethodDecl *ImpMethodDecl =
- IMPDecl->getClassMethod(Context, (*I)->getSelector());
+ ObjCMethodDecl *ImpMethodDecl =
+ IMPDecl->getClassMethod((*I)->getSelector());
ObjCMethodDecl *IntfMethodDecl =
- CDecl->getClassMethod(Context, (*I)->getSelector());
+ CDecl->getClassMethod((*I)->getSelector());
WarnConflictingTypedMethods(ImpMethodDecl, IntfMethodDecl);
}
}
@@ -1003,24 +998,23 @@ void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
// Check and see if instance methods in class interface have been
// implemented in the implementation class.
for (ObjCImplementationDecl::instmeth_iterator
- I = IMPDecl->instmeth_begin(Context),
- E = IMPDecl->instmeth_end(Context); I != E; ++I)
+ I = IMPDecl->instmeth_begin(), E = IMPDecl->instmeth_end(); I!=E; ++I)
InsMap.insert((*I)->getSelector());
// Check and see if properties declared in the interface have either 1)
// an implementation or 2) there is a @synthesize/@dynamic implementation
// of the property in the @implementation.
if (isa<ObjCInterfaceDecl>(CDecl))
- for (ObjCContainerDecl::prop_iterator P = CDecl->prop_begin(Context),
- E = CDecl->prop_end(Context); P != E; ++P) {
+ for (ObjCContainerDecl::prop_iterator P = CDecl->prop_begin(),
+ E = CDecl->prop_end(); P != E; ++P) {
ObjCPropertyDecl *Prop = (*P);
if (Prop->isInvalidDecl())
continue;
ObjCPropertyImplDecl *PI = 0;
// Is there a matching propery synthesize/dynamic?
for (ObjCImplDecl::propimpl_iterator
- I = IMPDecl->propimpl_begin(Context),
- EI = IMPDecl->propimpl_end(Context); I != EI; ++I)
+ I = IMPDecl->propimpl_begin(),
+ EI = IMPDecl->propimpl_end(); I != EI; ++I)
if ((*I)->getPropertyDecl() == Prop) {
PI = (*I);
break;
@@ -1046,8 +1040,8 @@ void Sema::ImplMethodsVsClassMethods(ObjCImplDecl* IMPDecl,
llvm::DenseSet<Selector> ClsMap;
for (ObjCImplementationDecl::classmeth_iterator
- I = IMPDecl->classmeth_begin(Context),
- E = IMPDecl->classmeth_end(Context); I != E; ++I)
+ I = IMPDecl->classmeth_begin(),
+ E = IMPDecl->classmeth_end(); I != E; ++I)
ClsMap.insert((*I)->getSelector());
// Check for type conflict of methods declared in a class/protocol and
@@ -1134,7 +1128,7 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
ObjCClassDecl *CDecl = ObjCClassDecl::Create(Context, CurContext, AtClassLoc,
&Interfaces[0],
Interfaces.size());
- CurContext->addDecl(Context, CDecl);
+ CurContext->addDecl(CDecl);
CheckObjCDeclScope(CDecl);
return DeclPtrTy::make(CDecl);
}
@@ -1348,8 +1342,8 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
ObjCContainerDecl *CD) {
ObjCMethodDecl *GetterMethod, *SetterMethod;
- GetterMethod = CD->getInstanceMethod(Context, property->getGetterName());
- SetterMethod = CD->getInstanceMethod(Context, property->getSetterName());
+ GetterMethod = CD->getInstanceMethod(property->getGetterName());
+ SetterMethod = CD->getInstanceMethod(property->getSetterName());
DiagnosePropertyAccessorMismatch(property, GetterMethod,
property->getLocation());
@@ -1384,7 +1378,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
ObjCPropertyDecl::Optional) ?
ObjCMethodDecl::Optional :
ObjCMethodDecl::Required);
- CD->addDecl(Context, GetterMethod);
+ CD->addDecl(GetterMethod);
} else
// A user declared getter will be synthesize when @synthesize of
// the property with the same name is seen in the @implementation
@@ -1415,7 +1409,7 @@ void Sema::ProcessPropertyDecl(ObjCPropertyDecl *property,
VarDecl::None,
0);
SetterMethod->setMethodParams(Context, &Argument, 1);
- CD->addDecl(Context, SetterMethod);
+ CD->addDecl(SetterMethod);
} else
// A user declared setter will be synthesize when @synthesize of
// the property with the same name is seen in the @implementation
@@ -1481,7 +1475,7 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclPtrTy classDecl,
<< Method->getDeclName();
Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
} else {
- DC->addDecl(Context, Method);
+ DC->addDecl(Method);
InsMap[Method->getSelector()] = Method;
/// The following allows us to typecheck messages to "id".
AddInstanceMethodToGlobalPool(Method);
@@ -1498,7 +1492,7 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclPtrTy classDecl,
<< Method->getDeclName();
Diag(PrevMethod->getLocation(), diag::note_previous_declaration);
} else {
- DC->addDecl(Context, Method);
+ DC->addDecl(Method);
ClsMap[Method->getSelector()] = Method;
/// The following allows us to typecheck messages to "Class".
AddFactoryMethodToGlobalPool(Method);
@@ -1524,8 +1518,8 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclPtrTy classDecl,
// ProcessPropertyDecl is responsible for diagnosing conflicts with any
// user-defined setter/getter. It also synthesizes setter/getter methods
// and adds them to the DeclContext and global method pools.
- for (ObjCContainerDecl::prop_iterator I = CDecl->prop_begin(Context),
- E = CDecl->prop_end(Context);
+ for (ObjCContainerDecl::prop_iterator I = CDecl->prop_begin(),
+ E = CDecl->prop_end();
I != E; ++I)
ProcessPropertyDecl(*I, CDecl);
CDecl->setAtEndLoc(AtEndLoc);
@@ -1683,11 +1677,11 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
if (ObjCImplementationDecl *ImpDecl =
dyn_cast<ObjCImplementationDecl>(ClassDecl)) {
if (MethodType == tok::minus) {
- PrevMethod = ImpDecl->getInstanceMethod(Context, Sel);
- ImpDecl->addInstanceMethod(Context, ObjCMethod);
+ PrevMethod = ImpDecl->getInstanceMethod(Sel);
+ ImpDecl->addInstanceMethod(ObjCMethod);
} else {
- PrevMethod = ImpDecl->getClassMethod(Context, Sel);
- ImpDecl->addClassMethod(Context, ObjCMethod);
+ PrevMethod = ImpDecl->getClassMethod(Sel);
+ ImpDecl->addClassMethod(ObjCMethod);
}
if (AttrList)
Diag(EndLoc, diag::warn_attribute_method_def);
@@ -1695,11 +1689,11 @@ Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
else if (ObjCCategoryImplDecl *CatImpDecl =
dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
if (MethodType == tok::minus) {
- PrevMethod = CatImpDecl->getInstanceMethod(Context, Sel);
- CatImpDecl->addInstanceMethod(Context, ObjCMethod);
+ PrevMethod = CatImpDecl->getInstanceMethod(Sel);
+ CatImpDecl->addInstanceMethod(ObjCMethod);
} else {
- PrevMethod = CatImpDecl->getClassMethod(Context, Sel);
- CatImpDecl->addClassMethod(Context, ObjCMethod);
+ PrevMethod = CatImpDecl->getClassMethod(Sel);
+ CatImpDecl->addClassMethod(ObjCMethod);
}
if (AttrList)
Diag(EndLoc, diag::warn_attribute_method_def);
@@ -1823,8 +1817,7 @@ Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
ObjCPropertyDecl *PIDecl = 0;
IdentifierInfo *PropertyId = FD.D.getIdentifier();
for (ObjCInterfaceDecl::prop_iterator
- I = CCPrimary->prop_begin(Context),
- E = CCPrimary->prop_end(Context);
+ I = CCPrimary->prop_begin(), E = CCPrimary->prop_end();
I != E; ++I)
if ((*I)->getIdentifier() == PropertyId) {
PIDecl = *I;
@@ -1870,7 +1863,7 @@ Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
ObjCPropertyDecl *PDecl = ObjCPropertyDecl::Create(Context, DC,
FD.D.getIdentifierLoc(),
FD.D.getIdentifier(), T);
- DC->addDecl(Context, PDecl);
+ DC->addDecl(PDecl);
if (T->isArrayType() || T->isFunctionType()) {
Diag(AtLoc, diag::err_property_type) << T;
@@ -1951,7 +1944,7 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
"ActOnPropertyImplDecl - @implementation without @interface");
// Look for this property declaration in the @implementation's @interface
- property = IDecl->FindPropertyDeclaration(Context, PropertyId);
+ property = IDecl->FindPropertyDeclaration(PropertyId);
if (!property) {
Diag(PropertyLoc, diag::error_bad_property_decl) << IDecl->getDeclName();
return DeclPtrTy();
@@ -1975,7 +1968,7 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
if (!Category)
return DeclPtrTy();
// Look for this property declaration in @implementation's category
- property = Category->FindPropertyDeclaration(Context, PropertyId);
+ property = Category->FindPropertyDeclaration(PropertyId);
if (!property) {
Diag(PropertyLoc, diag::error_bad_category_property_decl)
<< Category->getDeclName();
@@ -1994,7 +1987,7 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
QualType PropType = Context.getCanonicalType(property->getType());
// Check that this is a previously declared 'ivar' in 'IDecl' interface
ObjCInterfaceDecl *ClassDeclared;
- Ivar = IDecl->lookupInstanceVariable(Context, PropertyIvar, ClassDeclared);
+ Ivar = IDecl->lookupInstanceVariable(PropertyIvar, ClassDeclared);
if (!Ivar) {
DeclContext *EnclosingContext = cast_or_null<DeclContext>(IDecl);
assert(EnclosingContext &&
@@ -2004,7 +1997,7 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
ObjCIvarDecl::Public,
(Expr *)0);
Ivar->setLexicalDeclContext(IDecl);
- IDecl->addDecl(Context, Ivar);
+ IDecl->addDecl(Ivar);
property->setPropertyIvarDecl(Ivar);
if (!getLangOptions().ObjCNonFragileABI)
Diag(PropertyLoc, diag::error_missing_property_ivar_decl) << PropertyId;
@@ -2071,7 +2064,7 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
if (IC) {
if (Synthesize)
if (ObjCPropertyImplDecl *PPIDecl =
- IC->FindPropertyImplIvarDecl(Context, PropertyIvar)) {
+ IC->FindPropertyImplIvarDecl(PropertyIvar)) {
Diag(PropertyLoc, diag::error_duplicate_ivar_use)
<< PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
<< PropertyIvar;
@@ -2079,17 +2072,17 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
}
if (ObjCPropertyImplDecl *PPIDecl
- = IC->FindPropertyImplDecl(Context, PropertyId)) {
+ = IC->FindPropertyImplDecl(PropertyId)) {
Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
return DeclPtrTy();
}
- IC->addPropertyImplementation(Context, PIDecl);
+ IC->addPropertyImplementation(PIDecl);
}
else {
if (Synthesize)
if (ObjCPropertyImplDecl *PPIDecl =
- CatImplClass->FindPropertyImplIvarDecl(Context, PropertyIvar)) {
+ CatImplClass->FindPropertyImplIvarDecl(PropertyIvar)) {
Diag(PropertyLoc, diag::error_duplicate_ivar_use)
<< PropertyId << PPIDecl->getPropertyDecl()->getIdentifier()
<< PropertyIvar;
@@ -2097,12 +2090,12 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
}
if (ObjCPropertyImplDecl *PPIDecl =
- CatImplClass->FindPropertyImplDecl(Context, PropertyId)) {
+ CatImplClass->FindPropertyImplDecl(PropertyId)) {
Diag(PropertyLoc, diag::error_property_implemented) << PropertyId;
Diag(PPIDecl->getLocation(), diag::note_previous_declaration);
return DeclPtrTy();
}
- CatImplClass->addPropertyImplementation(Context, PIDecl);
+ CatImplClass->addPropertyImplementation(PIDecl);
}
return DeclPtrTy::make(PIDecl);
@@ -2154,7 +2147,7 @@ void Sema::ActOnDefs(Scope *S, DeclPtrTy TagD, SourceLocation DeclStart,
if (getLangOptions().CPlusPlus)
PushOnScopeChains(cast<FieldDecl>(FD), S);
else if (RecordDecl *Record = dyn_cast<RecordDecl>(TagD.getAs<Decl>()))
- Record->addDecl(Context, FD);
+ Record->addDecl(FD);
}
}
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 383edeca07a0..a5e508396422 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -39,7 +39,7 @@ using namespace clang;
/// referenced), false otherwise.
bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) {
// See if the decl is deprecated.
- if (D->getAttr<DeprecatedAttr>(Context)) {
+ if (D->getAttr<DeprecatedAttr>()) {
// Implementing deprecated stuff requires referencing deprecated
// stuff. Don't warn if we are implementing a deprecated
// construct.
@@ -48,7 +48,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) {
if (NamedDecl *ND = getCurFunctionOrMethodDecl()) {
// If this reference happens *in* a deprecated function or method, don't
// warn.
- isSilenced = ND->getAttr<DeprecatedAttr>(Context);
+ isSilenced = ND->getAttr<DeprecatedAttr>();
// If this is an Objective-C method implementation, check to see if the
// method was deprecated on the declaration, not the definition.
@@ -58,10 +58,9 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) {
if (ObjCImplementationDecl *Impl
= dyn_cast<ObjCImplementationDecl>(MD->getParent())) {
- MD = Impl->getClassInterface()->getMethod(Context,
- MD->getSelector(),
+ MD = Impl->getClassInterface()->getMethod(MD->getSelector(),
MD->isInstanceMethod());
- isSilenced |= MD && MD->getAttr<DeprecatedAttr>(Context);
+ isSilenced |= MD && MD->getAttr<DeprecatedAttr>();
}
}
}
@@ -80,7 +79,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) {
}
// See if the decl is unavailable
- if (D->getAttr<UnavailableAttr>(Context)) {
+ if (D->getAttr<UnavailableAttr>()) {
Diag(Loc, diag::warn_unavailable) << D->getDeclName();
Diag(D->getLocation(), diag::note_unavailable_here) << 0;
}
@@ -95,7 +94,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) {
void Sema::DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc,
Expr **Args, unsigned NumArgs)
{
- const SentinelAttr *attr = D->getAttr<SentinelAttr>(Context);
+ const SentinelAttr *attr = D->getAttr<SentinelAttr>();
if (!attr)
return;
int sentinelPos = attr->getSentinel();
@@ -673,8 +672,8 @@ static Decl *getObjectForAnonymousRecordDecl(ASTContext &Context,
// operation rather than a slow walk through DeclContext's vector (which
// itself will be eliminated). DeclGroups might make this even better.
DeclContext *Ctx = Record->getDeclContext();
- for (DeclContext::decl_iterator D = Ctx->decls_begin(Context),
- DEnd = Ctx->decls_end(Context);
+ for (DeclContext::decl_iterator D = Ctx->decls_begin(),
+ DEnd = Ctx->decls_end();
D != DEnd; ++D) {
if (*D == Record) {
// The object for the anonymous struct/union directly
@@ -877,8 +876,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
if (D == 0 || D->isDefinedOutsideFunctionOrMethod()) {
ObjCInterfaceDecl *IFace = getCurMethodDecl()->getClassInterface();
ObjCInterfaceDecl *ClassDeclared;
- if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(Context, II,
- ClassDeclared)) {
+ if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II, ClassDeclared)) {
// Check if referencing a field with __attribute__((deprecated)).
if (DiagnoseUseOfDecl(IV, Loc))
return ExprError();
@@ -915,8 +913,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
// We should warn if a local variable hides an ivar.
ObjCInterfaceDecl *IFace = getCurMethodDecl()->getClassInterface();
ObjCInterfaceDecl *ClassDeclared;
- if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(Context, II,
- ClassDeclared)) {
+ if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II, ClassDeclared)) {
if (IV->getAccessControl() != ObjCIvarDecl::Private ||
IFace == ClassDeclared)
Diag(Loc, diag::warn_ivar_use_hidden) << IV->getDeclName();
@@ -973,7 +970,64 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
return ExprError(Diag(Loc, diag::err_undeclared_var_use) << Name);
}
}
+
+ if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
+ // Warn about constructs like:
+ // if (void *X = foo()) { ... } else { X }.
+ // In the else block, the pointer is always false.
+
+ // FIXME: In a template instantiation, we don't have scope
+ // information to check this property.
+ if (Var->isDeclaredInCondition() && Var->getType()->isScalarType()) {
+ Scope *CheckS = S;
+ while (CheckS) {
+ if (CheckS->isWithinElse() &&
+ CheckS->getControlParent()->isDeclScope(DeclPtrTy::make(Var))) {
+ if (Var->getType()->isBooleanType())
+ ExprError(Diag(Loc, diag::warn_value_always_false)
+ << Var->getDeclName());
+ else
+ ExprError(Diag(Loc, diag::warn_value_always_zero)
+ << Var->getDeclName());
+ break;
+ }
+
+ // Move up one more control parent to check again.
+ CheckS = CheckS->getControlParent();
+ if (CheckS)
+ CheckS = CheckS->getParent();
+ }
+ }
+ } else if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D)) {
+ if (!getLangOptions().CPlusPlus && !Func->hasPrototype()) {
+ // C99 DR 316 says that, if a function type comes from a
+ // function definition (without a prototype), that type is only
+ // used for checking compatibility. Therefore, when referencing
+ // the function, we pretend that we don't have the full function
+ // type.
+ if (DiagnoseUseOfDecl(Func, Loc))
+ return ExprError();
+
+ QualType T = Func->getType();
+ QualType NoProtoType = T;
+ if (const FunctionProtoType *Proto = T->getAsFunctionProtoType())
+ NoProtoType = Context.getFunctionNoProtoType(Proto->getResultType());
+ return BuildDeclRefExpr(Func, NoProtoType, Loc, false, false, SS);
+ }
+ }
+
+ return BuildDeclarationNameExpr(Loc, D, HasTrailingLParen, SS, isAddressOfOperand);
+}
+/// \brief Complete semantic analysis for a reference to the given declaration.
+Sema::OwningExprResult
+Sema::BuildDeclarationNameExpr(SourceLocation Loc, NamedDecl *D,
+ bool HasTrailingLParen,
+ const CXXScopeSpec *SS,
+ bool isAddressOfOperand) {
+ assert(D && "Cannot refer to a NULL declaration");
+ DeclarationName Name = D->getDeclName();
+
// If this is an expression of the form &Class::member, don't build an
// implicit member ref, because we want a pointer to the member in general,
// not any specific instance's member.
@@ -1097,51 +1151,11 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
// this check when we're going to perform argument-dependent lookup
// on this function name, because this might not be the function
// that overload resolution actually selects.
+ bool ADL = getLangOptions().CPlusPlus && (!SS || !SS->isSet()) &&
+ HasTrailingLParen;
if (!(ADL && isa<FunctionDecl>(VD)) && DiagnoseUseOfDecl(VD, Loc))
return ExprError();
- if (VarDecl *Var = dyn_cast<VarDecl>(VD)) {
- // Warn about constructs like:
- // if (void *X = foo()) { ... } else { X }.
- // In the else block, the pointer is always false.
-
- // FIXME: In a template instantiation, we don't have scope
- // information to check this property.
- if (Var->isDeclaredInCondition() && Var->getType()->isScalarType()) {
- Scope *CheckS = S;
- while (CheckS) {
- if (CheckS->isWithinElse() &&
- CheckS->getControlParent()->isDeclScope(DeclPtrTy::make(Var))) {
- if (Var->getType()->isBooleanType())
- ExprError(Diag(Loc, diag::warn_value_always_false)
- << Var->getDeclName());
- else
- ExprError(Diag(Loc, diag::warn_value_always_zero)
- << Var->getDeclName());
- break;
- }
-
- // Move up one more control parent to check again.
- CheckS = CheckS->getControlParent();
- if (CheckS)
- CheckS = CheckS->getParent();
- }
- }
- } else if (FunctionDecl *Func = dyn_cast<FunctionDecl>(VD)) {
- if (!getLangOptions().CPlusPlus && !Func->hasPrototype()) {
- // C99 DR 316 says that, if a function type comes from a
- // function definition (without a prototype), that type is only
- // used for checking compatibility. Therefore, when referencing
- // the function, we pretend that we don't have the full function
- // type.
- QualType T = Func->getType();
- QualType NoProtoType = T;
- if (const FunctionProtoType *Proto = T->getAsFunctionProtoType())
- NoProtoType = Context.getFunctionNoProtoType(Proto->getResultType());
- return BuildDeclRefExpr(VD, NoProtoType, Loc, false, false, SS);
- }
- }
-
// Only create DeclRefExpr's for valid Decl's.
if (VD->isInvalidDecl())
return ExprError();
@@ -1158,7 +1172,7 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
MarkDeclarationReferenced(Loc, VD);
QualType ExprTy = VD->getType().getNonReferenceType();
// The BlocksAttr indicates the variable is bound by-reference.
- if (VD->getAttr<BlocksAttr>(Context))
+ if (VD->getAttr<BlocksAttr>())
return Owned(new (Context) BlockDeclRefExpr(VD, ExprTy, Loc, true));
// This is to record that a 'const' was actually synthesize and added.
bool constAdded = !ExprTy.isConstQualified();
@@ -1310,8 +1324,8 @@ Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) {
// isExact will be set by GetFloatValue().
bool isExact = false;
- Res = new (Context) FloatingLiteral(Literal.GetFloatValue(Format, &isExact),
- &isExact, Ty, Tok.getLocation());
+ llvm::APFloat Val = Literal.GetFloatValue(Format, &isExact);
+ Res = new (Context) FloatingLiteral(Val, isExact, Ty, Tok.getLocation());
} else if (!Literal.isIntegerLiteral()) {
return ExprError();
@@ -1989,9 +2003,9 @@ static Decl *FindGetterNameDeclFromProtocolList(const ObjCProtocolDecl*PDecl,
const Selector &Sel,
ASTContext &Context) {
- if (ObjCPropertyDecl *PD = PDecl->FindPropertyDeclaration(Context, &Member))
+ if (ObjCPropertyDecl *PD = PDecl->FindPropertyDeclaration(&Member))
return PD;
- if (ObjCMethodDecl *OMD = PDecl->getInstanceMethod(Context, Sel))
+ if (ObjCMethodDecl *OMD = PDecl->getInstanceMethod(Sel))
return OMD;
for (ObjCProtocolDecl::protocol_iterator I = PDecl->protocol_begin(),
@@ -2011,12 +2025,12 @@ static Decl *FindGetterNameDecl(const ObjCObjectPointerType *QIdTy,
Decl *GDecl = 0;
for (ObjCObjectPointerType::qual_iterator I = QIdTy->qual_begin(),
E = QIdTy->qual_end(); I != E; ++I) {
- if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(Context, &Member)) {
+ if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(&Member)) {
GDecl = PD;
break;
}
// Also must look for a getter name which uses property syntax.
- if (ObjCMethodDecl *OMD = (*I)->getInstanceMethod(Context, Sel)) {
+ if (ObjCMethodDecl *OMD = (*I)->getInstanceMethod(Sel)) {
GDecl = OMD;
break;
}
@@ -2042,7 +2056,7 @@ ObjCMethodDecl *Sema::FindMethodInNestedImplementations(
ObjCMethodDecl *Method = 0;
if (ObjCImplementationDecl *ImpDecl
= LookupObjCImplementation(IFace->getIdentifier()))
- Method = ImpDecl->getInstanceMethod(Context, Sel);
+ Method = ImpDecl->getInstanceMethod(Sel);
if (!Method && IFace->getSuperClass())
return FindMethodInNestedImplementations(IFace->getSuperClass(), Sel);
@@ -2201,8 +2215,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
// (*Obj).ivar.
if (const ObjCInterfaceType *IFTy = BaseType->getAsObjCInterfaceType()) {
ObjCInterfaceDecl *ClassDeclared;
- if (ObjCIvarDecl *IV = IFTy->getDecl()->lookupInstanceVariable(Context,
- &Member,
+ if (ObjCIvarDecl *IV = IFTy->getDecl()->lookupInstanceVariable(&Member,
ClassDeclared)) {
// If the decl being referenced had an error, return an error for this
// sub-expr without emitting another error, in order to avoid cascading
@@ -2262,14 +2275,13 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
ObjCInterfaceDecl *IFace = IFTy->getDecl();
// Search for a declared property first.
- if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(Context,
- &Member)) {
+ if (ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(&Member)) {
// Check whether we can reference this property.
if (DiagnoseUseOfDecl(PD, MemberLoc))
return ExprError();
QualType ResTy = PD->getType();
Selector Sel = PP.getSelectorTable().getNullarySelector(&Member);
- ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Context, Sel);
+ ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);
if (DiagnosePropertyAccessorMismatch(PD, Getter, MemberLoc))
ResTy = Getter->getResultType();
return Owned(new (Context) ObjCPropertyRefExpr(PD, ResTy,
@@ -2279,8 +2291,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
// Check protocols on qualified interfaces.
for (ObjCInterfaceType::qual_iterator I = IFTy->qual_begin(),
E = IFTy->qual_end(); I != E; ++I)
- if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(Context,
- &Member)) {
+ if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(&Member)) {
// Check whether we can reference this property.
if (DiagnoseUseOfDecl(PD, MemberLoc))
return ExprError();
@@ -2296,7 +2307,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
// shared with the code in ActOnInstanceMessage.
Selector Sel = PP.getSelectorTable().getNullarySelector(&Member);
- ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Context, Sel);
+ ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel);
// If this reference is in an @implementation, check for 'private' methods.
if (!Getter)
@@ -2306,7 +2317,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
if (!Getter) {
for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Getter; i++) {
if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
- Getter = ObjCCategoryImpls[i]->getInstanceMethod(Context, Sel);
+ Getter = ObjCCategoryImpls[i]->getInstanceMethod(Sel);
}
}
if (Getter) {
@@ -2319,7 +2330,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
Selector SetterSel =
SelectorTable::constructSetterName(PP.getIdentifierTable(),
PP.getSelectorTable(), &Member);
- ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(Context, SetterSel);
+ ObjCMethodDecl *Setter = IFace->lookupInstanceMethod(SetterSel);
if (!Setter) {
// If this reference is in an @implementation, also check for 'private'
// methods.
@@ -2329,7 +2340,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
if (!Setter) {
for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) {
if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
- Setter = ObjCCategoryImpls[i]->getInstanceMethod(Context, SetterSel);
+ Setter = ObjCCategoryImpls[i]->getInstanceMethod(SetterSel);
}
}
@@ -2390,7 +2401,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
ObjCInterfaceDecl *IFace = MD->getClassInterface();
ObjCMethodDecl *Getter;
// FIXME: need to also look locally in the implementation.
- if ((Getter = IFace->lookupClassMethod(Context, Sel))) {
+ if ((Getter = IFace->lookupClassMethod(Sel))) {
// Check the use of this method.
if (DiagnoseUseOfDecl(Getter, MemberLoc))
return ExprError();
@@ -2400,7 +2411,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
Selector SetterSel =
SelectorTable::constructSetterName(PP.getIdentifierTable(),
PP.getSelectorTable(), &Member);
- ObjCMethodDecl *Setter = IFace->lookupClassMethod(Context, SetterSel);
+ ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
if (!Setter) {
// If this reference is in an @implementation, also check for 'private'
// methods.
@@ -2410,7 +2421,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
if (!Setter) {
for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) {
if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
- Setter = ObjCCategoryImpls[i]->getClassMethod(Context, SetterSel);
+ Setter = ObjCCategoryImpls[i]->getClassMethod(SetterSel);
}
}
@@ -2624,9 +2635,13 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
}
// If we're directly calling a function, get the appropriate declaration.
- DeclRefExpr *DRExpr = NULL;
+ // Also, in C++, keep track of whether we should perform argument-dependent
+ // lookup and whether there were any explicitly-specified template arguments.
Expr *FnExpr = Fn;
bool ADL = true;
+ bool HasExplicitTemplateArgs = 0;
+ const TemplateArgument *ExplicitTemplateArgs = 0;
+ unsigned NumExplicitTemplateArgs = 0;
while (true) {
if (ImplicitCastExpr *IcExpr = dyn_cast<ImplicitCastExpr>(FnExpr))
FnExpr = IcExpr->getSubExpr();
@@ -2639,14 +2654,41 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
cast<UnaryOperator>(FnExpr)->getOpcode()
== UnaryOperator::AddrOf) {
FnExpr = cast<UnaryOperator>(FnExpr)->getSubExpr();
- } else if ((DRExpr = dyn_cast<DeclRefExpr>(FnExpr))) {
+ } else if (DeclRefExpr *DRExpr = dyn_cast<DeclRefExpr>(FnExpr)) {
// Qualified names disable ADL (C++0x [basic.lookup.argdep]p1).
ADL &= !isa<QualifiedDeclRefExpr>(DRExpr);
+ NDecl = dyn_cast<NamedDecl>(DRExpr->getDecl());
break;
} else if (UnresolvedFunctionNameExpr *DepName
= dyn_cast<UnresolvedFunctionNameExpr>(FnExpr)) {
UnqualifiedName = DepName->getName();
break;
+ } else if (TemplateIdRefExpr *TemplateIdRef
+ = dyn_cast<TemplateIdRefExpr>(FnExpr)) {
+ NDecl = TemplateIdRef->getTemplateName().getAsTemplateDecl();
+ HasExplicitTemplateArgs = true;
+ ExplicitTemplateArgs = TemplateIdRef->getTemplateArgs();
+ NumExplicitTemplateArgs = TemplateIdRef->getNumTemplateArgs();
+
+ // C++ [temp.arg.explicit]p6:
+ // [Note: For simple function names, argument dependent lookup (3.4.2)
+ // applies even when the function name is not visible within the
+ // scope of the call. This is because the call still has the syntactic
+ // form of a function call (3.4.1). But when a function template with
+ // explicit template arguments is used, the call does not have the
+ // correct syntactic form unless there is a function template with
+ // that name visible at the point of the call. If no such name is
+ // visible, the call is not syntactically well-formed and
+ // argument-dependent lookup does not apply. If some such name is
+ // visible, argument dependent lookup applies and additional function
+ // templates may be found in other namespaces.
+ //
+ // The summary of this paragraph is that, if we get to this point and the
+ // template-id was not a qualified name, then argument-dependent lookup
+ // is still possible.
+ if (TemplateIdRef->getQualifier())
+ ADL = false;
+ break;
} else {
// Any kind of name that does not refer to a declaration (or
// set of declarations) disables ADL (C++0x [basic.lookup.argdep]p3).
@@ -2657,14 +2699,13 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
OverloadedFunctionDecl *Ovl = 0;
FunctionTemplateDecl *FunctionTemplate = 0;
- if (DRExpr) {
- FDecl = dyn_cast<FunctionDecl>(DRExpr->getDecl());
- if ((FunctionTemplate = dyn_cast<FunctionTemplateDecl>(DRExpr->getDecl())))
+ if (NDecl) {
+ FDecl = dyn_cast<FunctionDecl>(NDecl);
+ if ((FunctionTemplate = dyn_cast<FunctionTemplateDecl>(NDecl)))
FDecl = FunctionTemplate->getTemplatedDecl();
else
- FDecl = dyn_cast<FunctionDecl>(DRExpr->getDecl());
- Ovl = dyn_cast<OverloadedFunctionDecl>(DRExpr->getDecl());
- NDecl = dyn_cast<NamedDecl>(DRExpr->getDecl());
+ FDecl = dyn_cast<FunctionDecl>(NDecl);
+ Ovl = dyn_cast<OverloadedFunctionDecl>(NDecl);
}
if (Ovl || FunctionTemplate ||
@@ -2678,16 +2719,19 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
ADL = false;
if (Ovl || FunctionTemplate || ADL) {
- FDecl = ResolveOverloadedCallFn(Fn, DRExpr? DRExpr->getDecl() : 0,
- UnqualifiedName, LParenLoc, Args,
- NumArgs, CommaLocs, RParenLoc, ADL);
+ FDecl = ResolveOverloadedCallFn(Fn, NDecl, UnqualifiedName,
+ HasExplicitTemplateArgs,
+ ExplicitTemplateArgs,
+ NumExplicitTemplateArgs,
+ LParenLoc, Args, NumArgs, CommaLocs,
+ RParenLoc, ADL);
if (!FDecl)
return ExprError();
// Update Fn to refer to the actual function selected.
Expr *NewFn = 0;
if (QualifiedDeclRefExpr *QDRExpr
- = dyn_cast_or_null<QualifiedDeclRefExpr>(DRExpr))
+ = dyn_cast<QualifiedDeclRefExpr>(FnExpr))
NewFn = new (Context) QualifiedDeclRefExpr(FDecl, FDecl->getType(),
QDRExpr->getLocation(),
false, false,
@@ -2750,7 +2794,7 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
// Check if we have too few/too many template arguments, based
// on our knowledge of the function definition.
const FunctionDecl *Def = 0;
- if (FDecl->getBody(Context, Def) && NumArgs != Def->param_size()) {
+ if (FDecl->getBody(Def) && NumArgs != Def->param_size()) {
const FunctionProtoType *Proto =
Def->getType()->getAsFunctionProtoType();
if (!Proto || !(Proto->isVariadic() && NumArgs >= Def->param_size())) {
@@ -2860,7 +2904,7 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr) {
// GCC cast to union extension
RecordDecl *RD = castType->getAsRecordType()->getDecl();
RecordDecl::field_iterator Field, FieldEnd;
- for (Field = RD->field_begin(Context), FieldEnd = RD->field_end(Context);
+ for (Field = RD->field_begin(), FieldEnd = RD->field_end();
Field != FieldEnd; ++Field) {
if (Context.getCanonicalType(Field->getType()).getUnqualifiedType() ==
Context.getCanonicalType(castExpr->getType()).getUnqualifiedType()) {
@@ -2931,19 +2975,8 @@ bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty) {
bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, QualType SrcTy) {
assert(DestTy->isExtVectorType() && "Not an extended vector type!");
- // If SrcTy is also an ExtVectorType, the types must be identical unless
- // lax vector conversions is enabled.
- if (SrcTy->isExtVectorType()) {
- if (getLangOptions().LaxVectorConversions &&
- Context.getTypeSize(DestTy) == Context.getTypeSize(SrcTy))
- return false;
- if (DestTy != SrcTy)
- return Diag(R.getBegin(),diag::err_invalid_conversion_between_ext_vectors)
- << DestTy << SrcTy << R;
- return false;
- }
-
- // If SrcTy is a VectorType, then only the total size must match.
+ // If SrcTy is a VectorType, the total size must match to explicitly cast to
+ // an ExtVectorType.
if (SrcTy->isVectorType()) {
if (Context.getTypeSize(DestTy) != Context.getTypeSize(SrcTy))
return Diag(R.getBegin(),diag::err_invalid_conversion_between_ext_vectors)
@@ -2951,9 +2984,13 @@ bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, QualType SrcTy) {
return false;
}
- // All scalar -> ext vector "c-style" casts are legal; the appropriate
+ // All non-pointer scalars can be cast to ExtVector type. The appropriate
// conversion will take place first from scalar to elt type, and then
// splat from elt type to vector.
+ if (SrcTy->isPointerType())
+ return Diag(R.getBegin(),
+ diag::err_invalid_conversion_between_vector_and_scalar)
+ << DestTy << SrcTy << R;
return false;
}
@@ -3042,24 +3079,133 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
ImpCastExprToType(LHS, RHSTy); // promote the null to a pointer.
return RHSTy;
}
+ // Handle block pointer types.
+ if (LHSTy->isBlockPointerType() || RHSTy->isBlockPointerType()) {
+ if (!LHSTy->isBlockPointerType() || !RHSTy->isBlockPointerType()) {
+ if (LHSTy->isVoidPointerType() || RHSTy->isVoidPointerType()) {
+ QualType destType = Context.getPointerType(Context.VoidTy);
+ ImpCastExprToType(LHS, destType);
+ ImpCastExprToType(RHS, destType);
+ return destType;
+ }
+ Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
+ << LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
+ return QualType();
+ }
+ // We have 2 block pointer types.
+ if (Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) {
+ // Two identical block pointer types are always compatible.
+ return LHSTy;
+ }
+ // The block pointer types aren't identical, continue checking.
+ QualType lhptee = LHSTy->getAsBlockPointerType()->getPointeeType();
+ QualType rhptee = RHSTy->getAsBlockPointerType()->getPointeeType();
- const PointerType *LHSPT = LHSTy->getAsPointerType();
- const PointerType *RHSPT = RHSTy->getAsPointerType();
- const BlockPointerType *LHSBPT = LHSTy->getAsBlockPointerType();
- const BlockPointerType *RHSBPT = RHSTy->getAsBlockPointerType();
+ if (!Context.typesAreCompatible(lhptee.getUnqualifiedType(),
+ rhptee.getUnqualifiedType())) {
+ Diag(QuestionLoc, diag::warn_typecheck_cond_incompatible_pointers)
+ << LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
+ // In this situation, we assume void* type. No especially good
+ // reason, but this is what gcc does, and we do have to pick
+ // to get a consistent AST.
+ QualType incompatTy = Context.getPointerType(Context.VoidTy);
+ ImpCastExprToType(LHS, incompatTy);
+ ImpCastExprToType(RHS, incompatTy);
+ return incompatTy;
+ }
+ // The block pointer types are compatible.
+ ImpCastExprToType(LHS, LHSTy);
+ ImpCastExprToType(RHS, LHSTy);
+ return LHSTy;
+ }
+ // Need to handle "id<xx>" explicitly. Unlike "id", whose canonical type
+ // evaluates to "struct objc_object *" (and is handled above when comparing
+ // id with statically typed objects).
+ if (LHSTy->isObjCQualifiedIdType() || RHSTy->isObjCQualifiedIdType()) {
+ // GCC allows qualified id and any Objective-C type to devolve to
+ // id. Currently localizing to here until clear this should be
+ // part of ObjCQualifiedIdTypesAreCompatible.
+ if (ObjCQualifiedIdTypesAreCompatible(LHSTy, RHSTy, true) ||
+ (LHSTy->isObjCQualifiedIdType() &&
+ Context.isObjCObjectPointerType(RHSTy)) ||
+ (RHSTy->isObjCQualifiedIdType() &&
+ Context.isObjCObjectPointerType(LHSTy))) {
+ // FIXME: This is not the correct composite type. This only happens to
+ // work because id can more or less be used anywhere, however this may
+ // change the type of method sends.
- // Handle the case where both operands are pointers before we handle null
- // pointer constants in case both operands are null pointer constants.
- if ((LHSPT || LHSBPT) && (RHSPT || RHSBPT)) { // C99 6.5.15p3,6
+ // FIXME: gcc adds some type-checking of the arguments and emits
+ // (confusing) incompatible comparison warnings in some
+ // cases. Investigate.
+ QualType compositeType = Context.getObjCIdType();
+ ImpCastExprToType(LHS, compositeType);
+ ImpCastExprToType(RHS, compositeType);
+ return compositeType;
+ }
+ }
+ // Check constraints for Objective-C object pointers types.
+ if (Context.isObjCObjectPointerType(LHSTy) &&
+ Context.isObjCObjectPointerType(RHSTy)) {
+
+ if (Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) {
+ // Two identical object pointer types are always compatible.
+ return LHSTy;
+ }
+ // No need to check for block pointer types or qualified id types (they
+ // were handled above).
+ assert((LHSTy->isPointerType() && RHSTy->isPointerType()) &&
+ "Sema::CheckConditionalOperands(): Unexpected type");
+ QualType lhptee = LHSTy->getAsPointerType()->getPointeeType();
+ QualType rhptee = RHSTy->getAsPointerType()->getPointeeType();
+
+ QualType compositeType = LHSTy;
+
+ // If both operands are interfaces and either operand can be
+ // assigned to the other, use that type as the composite
+ // type. This allows
+ // xxx ? (A*) a : (B*) b
+ // where B is a subclass of A.
+ //
+ // Additionally, as for assignment, if either type is 'id'
+ // allow silent coercion. Finally, if the types are
+ // incompatible then make sure to use 'id' as the composite
+ // type so the result is acceptable for sending messages to.
+
+ // FIXME: Consider unifying with 'areComparableObjCPointerTypes'.
+ // It could return the composite type.
+ const ObjCInterfaceType* LHSIface = lhptee->getAsObjCInterfaceType();
+ const ObjCInterfaceType* RHSIface = rhptee->getAsObjCInterfaceType();
+ if (LHSIface && RHSIface &&
+ Context.canAssignObjCInterfaces(LHSIface, RHSIface)) {
+ compositeType = LHSTy;
+ } else if (LHSIface && RHSIface &&
+ Context.canAssignObjCInterfaces(RHSIface, LHSIface)) {
+ compositeType = RHSTy;
+ } else if (Context.isObjCIdStructType(lhptee) ||
+ Context.isObjCIdStructType(rhptee)) {
+ compositeType = Context.getObjCIdType();
+ } else {
+ Diag(QuestionLoc, diag::ext_typecheck_cond_incompatible_operands)
+ << LHSTy << RHSTy
+ << LHS->getSourceRange() << RHS->getSourceRange();
+ QualType incompatTy = Context.getObjCIdType();
+ ImpCastExprToType(LHS, incompatTy);
+ ImpCastExprToType(RHS, incompatTy);
+ return incompatTy;
+ }
+ // The object pointer types are compatible.
+ ImpCastExprToType(LHS, compositeType);
+ ImpCastExprToType(RHS, compositeType);
+ return compositeType;
+ }
+ // Check constraints for C object pointers types (C99 6.5.15p3,6).
+ if (LHSTy->isPointerType() && RHSTy->isPointerType()) {
// get the "pointed to" types
- QualType lhptee = (LHSPT ? LHSPT->getPointeeType()
- : LHSBPT->getPointeeType());
- QualType rhptee = (RHSPT ? RHSPT->getPointeeType()
- : RHSBPT->getPointeeType());
+ QualType lhptee = LHSTy->getAsPointerType()->getPointeeType();
+ QualType rhptee = RHSTy->getAsPointerType()->getPointeeType();
// ignore qualifiers on void (C99 6.5.15p3, clause 6)
- if (lhptee->isVoidType()
- && (RHSBPT || rhptee->isIncompleteOrObjectType())) {
+ if (lhptee->isVoidType() && rhptee->isIncompleteOrObjectType()) {
// Figure out necessary qualifiers (C99 6.5.15p6)
QualType destPointee=lhptee.getQualifiedType(rhptee.getCVRQualifiers());
QualType destType = Context.getPointerType(destPointee);
@@ -3067,8 +3213,7 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
ImpCastExprToType(RHS, destType); // promote to void*
return destType;
}
- if (rhptee->isVoidType()
- && (LHSBPT || lhptee->isIncompleteOrObjectType())) {
+ if (rhptee->isVoidType() && lhptee->isIncompleteOrObjectType()) {
QualType destPointee=rhptee.getQualifiedType(lhptee.getCVRQualifiers());
QualType destType = Context.getPointerType(destPointee);
ImpCastExprToType(LHS, destType); // add qualifiers if necessary
@@ -3076,62 +3221,12 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
return destType;
}
- bool sameKind = (LHSPT && RHSPT) || (LHSBPT && RHSBPT);
- if (sameKind
- && Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) {
+ if (Context.getCanonicalType(LHSTy) == Context.getCanonicalType(RHSTy)) {
// Two identical pointer types are always compatible.
return LHSTy;
}
-
- QualType compositeType = LHSTy;
-
- // If either type is an Objective-C object type then check
- // compatibility according to Objective-C.
- if (Context.isObjCObjectPointerType(LHSTy) ||
- Context.isObjCObjectPointerType(RHSTy)) {
- // If both operands are interfaces and either operand can be
- // assigned to the other, use that type as the composite
- // type. This allows
- // xxx ? (A*) a : (B*) b
- // where B is a subclass of A.
- //
- // Additionally, as for assignment, if either type is 'id'
- // allow silent coercion. Finally, if the types are
- // incompatible then make sure to use 'id' as the composite
- // type so the result is acceptable for sending messages to.
-
- // FIXME: Consider unifying with 'areComparableObjCPointerTypes'.
- // It could return the composite type.
- const ObjCInterfaceType* LHSIface = lhptee->getAsObjCInterfaceType();
- const ObjCInterfaceType* RHSIface = rhptee->getAsObjCInterfaceType();
- if (LHSIface && RHSIface &&
- Context.canAssignObjCInterfaces(LHSIface, RHSIface)) {
- compositeType = LHSTy;
- } else if (LHSIface && RHSIface &&
- Context.canAssignObjCInterfaces(RHSIface, LHSIface)) {
- compositeType = RHSTy;
- } else if (Context.isObjCIdStructType(lhptee) ||
- Context.isObjCIdStructType(rhptee)) {
- compositeType = Context.getObjCIdType();
- } else if (LHSBPT || RHSBPT) {
- if (!sameKind
- || !Context.typesAreCompatible(lhptee.getUnqualifiedType(),
- rhptee.getUnqualifiedType()))
- Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
- << LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
- return QualType();
- } else {
- Diag(QuestionLoc, diag::ext_typecheck_cond_incompatible_operands)
- << LHSTy << RHSTy
- << LHS->getSourceRange() << RHS->getSourceRange();
- QualType incompatTy = Context.getObjCIdType();
- ImpCastExprToType(LHS, incompatTy);
- ImpCastExprToType(RHS, incompatTy);
- return incompatTy;
- }
- } else if (!sameKind
- || !Context.typesAreCompatible(lhptee.getUnqualifiedType(),
- rhptee.getUnqualifiedType())) {
+ if (!Context.typesAreCompatible(lhptee.getUnqualifiedType(),
+ rhptee.getUnqualifiedType())) {
Diag(QuestionLoc, diag::warn_typecheck_cond_incompatible_pointers)
<< LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
// In this situation, we assume void* type. No especially good
@@ -3149,11 +3244,11 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
// type.
// FIXME: Need to calculate the composite type.
// FIXME: Need to add qualifiers
- ImpCastExprToType(LHS, compositeType);
- ImpCastExprToType(RHS, compositeType);
- return compositeType;
+ ImpCastExprToType(LHS, LHSTy);
+ ImpCastExprToType(RHS, LHSTy);
+ return LHSTy;
}
-
+
// GCC compatibility: soften pointer/integer mismatch.
if (RHSTy->isPointerType() && LHSTy->isIntegerType()) {
Diag(QuestionLoc, diag::warn_typecheck_cond_pointer_integer_mismatch)
@@ -3168,32 +3263,6 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
return LHSTy;
}
- // Need to handle "id<xx>" explicitly. Unlike "id", whose canonical type
- // evaluates to "struct objc_object *" (and is handled above when comparing
- // id with statically typed objects).
- if (LHSTy->isObjCQualifiedIdType() || RHSTy->isObjCQualifiedIdType()) {
- // GCC allows qualified id and any Objective-C type to devolve to
- // id. Currently localizing to here until clear this should be
- // part of ObjCQualifiedIdTypesAreCompatible.
- if (ObjCQualifiedIdTypesAreCompatible(LHSTy, RHSTy, true) ||
- (LHSTy->isObjCQualifiedIdType() &&
- Context.isObjCObjectPointerType(RHSTy)) ||
- (RHSTy->isObjCQualifiedIdType() &&
- Context.isObjCObjectPointerType(LHSTy))) {
- // FIXME: This is not the correct composite type. This only happens to
- // work because id can more or less be used anywhere, however this may
- // change the type of method sends.
-
- // FIXME: gcc adds some type-checking of the arguments and emits
- // (confusing) incompatible comparison warnings in some
- // cases. Investigate.
- QualType compositeType = Context.getObjCIdType();
- ImpCastExprToType(LHS, compositeType);
- ImpCastExprToType(RHS, compositeType);
- return compositeType;
- }
- }
-
// Otherwise, the operands are not compatible.
Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
<< LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
@@ -3385,12 +3454,16 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
return IncompatibleObjCQualifiedId;
}
+ // Allow scalar to ExtVector assignments, and assignments of an ExtVector type
+ // to the same ExtVector type.
+ if (lhsType->isExtVectorType()) {
+ if (rhsType->isExtVectorType())
+ return lhsType == rhsType ? Compatible : Incompatible;
+ if (!rhsType->isVectorType() && rhsType->isArithmeticType())
+ return Compatible;
+ }
+
if (lhsType->isVectorType() || rhsType->isVectorType()) {
- // For ExtVector, allow vector splats; float -> <n x float>
- if (const ExtVectorType *LV = lhsType->getAsExtVectorType())
- if (LV->getElementType() == rhsType)
- return Compatible;
-
// If we are allowing lax vector conversions, and LHS and RHS are both
// vectors, the total size only needs to be the same. This is a bitcast;
// no bits are changed but the result type is different.
@@ -3492,15 +3565,15 @@ Sema::CheckTransparentUnionArgumentConstraints(QualType ArgType, Expr *&rExpr) {
// If the ArgType is a Union type, we want to handle a potential
// transparent_union GCC extension.
const RecordType *UT = ArgType->getAsUnionType();
- if (!UT || !UT->getDecl()->hasAttr<TransparentUnionAttr>(Context))
+ if (!UT || !UT->getDecl()->hasAttr<TransparentUnionAttr>())
return Incompatible;
// The field to initialize within the transparent union.
RecordDecl *UD = UT->getDecl();
FieldDecl *InitField = 0;
// It's compatible if the expression matches any of the fields.
- for (RecordDecl::field_iterator it = UD->field_begin(Context),
- itend = UD->field_end(Context);
+ for (RecordDecl::field_iterator it = UD->field_begin(),
+ itend = UD->field_end();
it != itend; ++it) {
if (it->getType()->isPointerType()) {
// If the transparent union contains a pointer type, we allow:
@@ -3617,33 +3690,36 @@ inline QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex,
}
}
- // If the lhs is an extended vector and the rhs is a scalar of the same type
- // or a literal, promote the rhs to the vector type.
- if (const ExtVectorType *V = lhsType->getAsExtVectorType()) {
- QualType eltType = V->getElementType();
-
- if ((eltType->getAsBuiltinType() == rhsType->getAsBuiltinType()) ||
- (eltType->isIntegerType() && isa<IntegerLiteral>(rex)) ||
- (eltType->isFloatingType() && isa<FloatingLiteral>(rex))) {
- ImpCastExprToType(rex, lhsType);
- return lhsType;
- }
+ // Canonicalize the ExtVector to the LHS, remember if we swapped so we can
+ // swap back (so that we don't reverse the inputs to a subtract, for instance.
+ bool swapped = false;
+ if (rhsType->isExtVectorType()) {
+ swapped = true;
+ std::swap(rex, lex);
+ std::swap(rhsType, lhsType);
}
-
- // If the rhs is an extended vector and the lhs is a scalar of the same type,
- // promote the lhs to the vector type.
- if (const ExtVectorType *V = rhsType->getAsExtVectorType()) {
- QualType eltType = V->getElementType();
-
- if ((eltType->getAsBuiltinType() == lhsType->getAsBuiltinType()) ||
- (eltType->isIntegerType() && isa<IntegerLiteral>(lex)) ||
- (eltType->isFloatingType() && isa<FloatingLiteral>(lex))) {
- ImpCastExprToType(lex, rhsType);
- return rhsType;
+
+ // Handle the case of an ext vector and scalar.
+ if (const ExtVectorType *LV = lhsType->getAsExtVectorType()) {
+ QualType EltTy = LV->getElementType();
+ if (EltTy->isIntegralType() && rhsType->isIntegralType()) {
+ if (Context.getIntegerTypeOrder(EltTy, rhsType) >= 0) {
+ ImpCastExprToType(rex, lhsType);
+ if (swapped) std::swap(rex, lex);
+ return lhsType;
+ }
+ }
+ if (EltTy->isRealFloatingType() && rhsType->isScalarType() &&
+ rhsType->isRealFloatingType()) {
+ if (Context.getFloatingTypeOrder(EltTy, rhsType) >= 0) {
+ ImpCastExprToType(rex, lhsType);
+ if (swapped) std::swap(rex, lex);
+ return lhsType;
+ }
}
}
-
- // You cannot convert between vector values of different size.
+
+ // Vectors of different size or scalar and non-ext-vector are errors.
Diag(Loc, diag::err_typecheck_vector_not_convertable)
<< lex->getType() << rex->getType()
<< lex->getSourceRange() << rex->getSourceRange();
@@ -4034,6 +4110,17 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
QualType RCanPointeeTy =
Context.getCanonicalType(rType->getAsPointerType()->getPointeeType());
+ if (rType->isFunctionPointerType() || lType->isFunctionPointerType()) {
+ if (isRelational) {
+ Diag(Loc, diag::ext_typecheck_ordered_comparison_of_function_pointers)
+ << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+ }
+ }
+ if (((!LHSIsNull || isRelational) && LCanPointeeTy->isVoidType()) !=
+ ((!RHSIsNull || isRelational) && RCanPointeeTy->isVoidType())) {
+ Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
+ << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+ }
// Simple check: if the pointee types are identical, we're done.
if (LCanPointeeTy == RCanPointeeTy)
return ResultTy;
@@ -4146,7 +4233,10 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
}
if ((lType->isPointerType() || lType->isObjCQualifiedIdType()) &&
rType->isIntegerType()) {
- if (!RHSIsNull)
+ if (isRelational)
+ Diag(Loc, diag::ext_typecheck_ordered_comparison_of_pointer_integer)
+ << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+ else if (!RHSIsNull)
Diag(Loc, diag::ext_typecheck_comparison_of_pointer_integer)
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
ImpCastExprToType(rex, lType); // promote the integer to pointer
@@ -4154,7 +4244,10 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
}
if (lType->isIntegerType() &&
(rType->isPointerType() || rType->isObjCQualifiedIdType())) {
- if (!LHSIsNull)
+ if (isRelational)
+ Diag(Loc, diag::ext_typecheck_ordered_comparison_of_pointer_integer)
+ << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+ else if (!LHSIsNull)
Diag(Loc, diag::ext_typecheck_comparison_of_pointer_integer)
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
ImpCastExprToType(lex, rType); // promote the integer to pointer
@@ -5226,7 +5319,7 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) {
CurBlock->hasPrototype = true;
CurBlock->isVariadic = false;
// Check for a valid sentinel attribute on this block.
- if (CurBlock->TheDecl->getAttr<SentinelAttr>(Context)) {
+ if (CurBlock->TheDecl->getAttr<SentinelAttr>()) {
Diag(ParamInfo.getAttributes()->getLoc(),
diag::warn_attribute_sentinel_not_variadic) << 1;
// FIXME: remove the attribute.
@@ -5275,7 +5368,7 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) {
// Check for a valid sentinel attribute on this block.
if (!CurBlock->isVariadic &&
- CurBlock->TheDecl->getAttr<SentinelAttr>(Context)) {
+ CurBlock->TheDecl->getAttr<SentinelAttr>()) {
Diag(ParamInfo.getAttributes()->getLoc(),
diag::warn_attribute_sentinel_not_variadic) << 1;
// FIXME: remove the attribute.
@@ -5607,13 +5700,13 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
// Implicit instantiation of function templates and member functions of
// class templates.
- if (!Function->getBody(Context)) {
+ if (!Function->getBody()) {
// FIXME: distinguish between implicit instantiations of function
// templates and explicit specializations (the latter don't get
// instantiated, naturally).
if (Function->getInstantiatedFromMemberFunction() ||
Function->getPrimaryTemplate())
- PendingImplicitInstantiations.push(std::make_pair(Function, Loc));
+ PendingImplicitInstantiations.push_back(std::make_pair(Function, Loc));
}
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index bc8fc4eae502..7afa5941dad9 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -552,7 +552,7 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range,
bool AllowMissing, FunctionDecl *&Operator)
{
DeclContext::lookup_iterator Alloc, AllocEnd;
- llvm::tie(Alloc, AllocEnd) = Ctx->lookup(Context, Name);
+ llvm::tie(Alloc, AllocEnd) = Ctx->lookup(Name);
if (Alloc == AllocEnd) {
if (AllowMissing)
return false;
@@ -657,7 +657,7 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
// Check if this function is already declared.
{
DeclContext::lookup_iterator Alloc, AllocEnd;
- for (llvm::tie(Alloc, AllocEnd) = GlobalCtx->lookup(Context, Name);
+ for (llvm::tie(Alloc, AllocEnd) = GlobalCtx->lookup(Name);
Alloc != AllocEnd; ++Alloc) {
// FIXME: Do we need to check for default arguments here?
FunctionDecl *Func = cast<FunctionDecl>(*Alloc);
@@ -680,7 +680,7 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
// FIXME: Also add this declaration to the IdentifierResolver, but
// make sure it is at the end of the chain to coincide with the
// global scope.
- ((DeclContext *)TUScope->getEntity())->addDecl(Context, Alloc);
+ ((DeclContext *)TUScope->getEntity())->addDecl(Alloc);
}
/// ActOnCXXDelete - Parsed a C++ 'delete' expression (C++ 5.3.5), as in:
@@ -1567,7 +1567,7 @@ Sema::OwningExprResult Sema::MaybeBindToTemporary(Expr *E) {
CXXTemporary *Temp = CXXTemporary::Create(Context,
RD->getDestructor(Context));
ExprTemporaries.push_back(Temp);
- MarcDestructorReferenced(E->getExprLoc(), E->getType());
+ MarkDestructorReferenced(E->getExprLoc(), E->getType());
// FIXME: Add the temporary to the temporaries vector.
return Owned(CXXBindTemporaryExpr::Create(Context, Temp, E));
}
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index f1869f903719..7bb6b44c39cf 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -243,13 +243,13 @@ ObjCMethodDecl *Sema::LookupPrivateClassMethod(Selector Sel,
while (ClassDecl && !Method) {
if (ObjCImplementationDecl *ImpDecl
= LookupObjCImplementation(ClassDecl->getIdentifier()))
- Method = ImpDecl->getClassMethod(Context, Sel);
+ Method = ImpDecl->getClassMethod(Sel);
// Look through local category implementations associated with the class.
if (!Method) {
for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Method; i++) {
if (ObjCCategoryImpls[i]->getClassInterface() == ClassDecl)
- Method = ObjCCategoryImpls[i]->getClassMethod(Context, Sel);
+ Method = ObjCCategoryImpls[i]->getClassMethod(Sel);
}
}
@@ -257,7 +257,7 @@ ObjCMethodDecl *Sema::LookupPrivateClassMethod(Selector Sel,
// But only in the root. This matches gcc's behaviour and what the
// runtime expects.
if (!Method && !ClassDecl->getSuperClass()) {
- Method = ClassDecl->lookupInstanceMethod(Context, Sel);
+ Method = ClassDecl->lookupInstanceMethod(Sel);
// Look through local category implementations associated
// with the root class.
if (!Method)
@@ -276,13 +276,13 @@ ObjCMethodDecl *Sema::LookupPrivateInstanceMethod(Selector Sel,
// If we have implementations in scope, check "private" methods.
if (ObjCImplementationDecl *ImpDecl
= LookupObjCImplementation(ClassDecl->getIdentifier()))
- Method = ImpDecl->getInstanceMethod(Context, Sel);
+ Method = ImpDecl->getInstanceMethod(Sel);
// Look through local category implementations associated with the class.
if (!Method) {
for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Method; i++) {
if (ObjCCategoryImpls[i]->getClassInterface() == ClassDecl)
- Method = ObjCCategoryImpls[i]->getInstanceMethod(Context, Sel);
+ Method = ObjCCategoryImpls[i]->getInstanceMethod(Sel);
}
}
ClassDecl = ClassDecl->getSuperClass();
@@ -301,7 +301,7 @@ Action::OwningExprResult Sema::ActOnClassPropertyRefExpr(
// Search for a declared property first.
Selector Sel = PP.getSelectorTable().getNullarySelector(&propertyName);
- ObjCMethodDecl *Getter = IFace->lookupClassMethod(Context, Sel);
+ ObjCMethodDecl *Getter = IFace->lookupClassMethod(Sel);
// If this reference is in an @implementation, check for 'private' methods.
if (!Getter)
@@ -309,7 +309,7 @@ Action::OwningExprResult Sema::ActOnClassPropertyRefExpr(
if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
if (ObjCImplementationDecl *ImpDecl
= LookupObjCImplementation(ClassDecl->getIdentifier()))
- Getter = ImpDecl->getClassMethod(Context, Sel);
+ Getter = ImpDecl->getClassMethod(Sel);
if (Getter) {
// FIXME: refactor/share with ActOnMemberReference().
@@ -323,7 +323,7 @@ Action::OwningExprResult Sema::ActOnClassPropertyRefExpr(
SelectorTable::constructSetterName(PP.getIdentifierTable(),
PP.getSelectorTable(), &propertyName);
- ObjCMethodDecl *Setter = IFace->lookupClassMethod(Context, SetterSel);
+ ObjCMethodDecl *Setter = IFace->lookupClassMethod(SetterSel);
if (!Setter) {
// If this reference is in an @implementation, also check for 'private'
// methods.
@@ -331,13 +331,13 @@ Action::OwningExprResult Sema::ActOnClassPropertyRefExpr(
if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
if (ObjCImplementationDecl *ImpDecl
= LookupObjCImplementation(ClassDecl->getIdentifier()))
- Setter = ImpDecl->getClassMethod(Context, SetterSel);
+ Setter = ImpDecl->getClassMethod(SetterSel);
}
// Look through local category implementations associated with the class.
if (!Setter) {
for (unsigned i = 0; i < ObjCCategoryImpls.size() && !Setter; i++) {
if (ObjCCategoryImpls[i]->getClassInterface() == IFace)
- Setter = ObjCCategoryImpls[i]->getClassMethod(Context, SetterSel);
+ Setter = ObjCCategoryImpls[i]->getClassMethod(SetterSel);
}
}
@@ -450,7 +450,7 @@ Sema::ExprResult Sema::ActOnClassMessage(
<< Method->getDeclName();
}
if (!Method)
- Method = ClassDecl->lookupClassMethod(Context, Sel);
+ Method = ClassDecl->lookupClassMethod(Sel);
// If we have an implementation in scope, check "private" methods.
if (!Method)
@@ -507,7 +507,7 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
// If we have an interface in scope, check 'super' methods.
if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface())
if (ObjCInterfaceDecl *SuperDecl = ClassDecl->getSuperClass()) {
- Method = SuperDecl->lookupInstanceMethod(Context, Sel);
+ Method = SuperDecl->lookupInstanceMethod(Sel);
if (!Method)
// If we have implementations in scope, check "private" methods.
@@ -550,7 +550,7 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) {
// First check the public methods in the class interface.
- Method = ClassDecl->lookupClassMethod(Context, Sel);
+ Method = ClassDecl->lookupClassMethod(Sel);
if (!Method)
Method = LookupPrivateClassMethod(Sel, ClassDecl);
@@ -596,10 +596,10 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
for (ObjCObjectPointerType::qual_iterator I = QIdTy->qual_begin(),
E = QIdTy->qual_end(); I != E; ++I) {
ObjCProtocolDecl *PDecl = *I;
- if (PDecl && (Method = PDecl->lookupInstanceMethod(Context, Sel)))
+ if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel)))
break;
// Since we aren't supporting "Class<foo>", look for a class method.
- if (PDecl && (Method = PDecl->lookupClassMethod(Context, Sel)))
+ if (PDecl && (Method = PDecl->lookupClassMethod(Sel)))
break;
}
} else if (const ObjCInterfaceType *OCIType =
@@ -610,13 +610,13 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
// FIXME: consider using LookupInstanceMethodInGlobalPool, since it will be
// faster than the following method (which can do *many* linear searches).
// The idea is to add class info to InstanceMethodPool.
- Method = ClassDecl->lookupInstanceMethod(Context, Sel);
+ Method = ClassDecl->lookupInstanceMethod(Sel);
if (!Method) {
// Search protocol qualifiers.
for (ObjCQualifiedInterfaceType::qual_iterator QI = OCIType->qual_begin(),
E = OCIType->qual_end(); QI != E; ++QI) {
- if ((Method = (*QI)->lookupInstanceMethod(Context, Sel)))
+ if ((Method = (*QI)->lookupInstanceMethod(Sel)))
break;
}
}
diff --git a/lib/Sema/SemaInherit.cpp b/lib/Sema/SemaInherit.cpp
index 28ca5f64ef59..2f914f14a81f 100644
--- a/lib/Sema/SemaInherit.cpp
+++ b/lib/Sema/SemaInherit.cpp
@@ -187,7 +187,7 @@ bool Sema::LookupInBases(CXXRecordDecl *Class,
= (Context.getCanonicalType(BaseSpec->getType()) == Criteria.Base);
break;
case MemberLookupCriteria::LK_NamedMember:
- Paths.ScratchPath.Decls = BaseRecord->lookup(Context, Criteria.Name);
+ Paths.ScratchPath.Decls = BaseRecord->lookup(Criteria.Name);
while (Paths.ScratchPath.Decls.first != Paths.ScratchPath.Decls.second) {
if (isAcceptableLookupResult(*Paths.ScratchPath.Decls.first,
Criteria.NameKind, Criteria.IDNS)) {
@@ -199,7 +199,7 @@ bool Sema::LookupInBases(CXXRecordDecl *Class,
break;
case MemberLookupCriteria::LK_OverriddenMember:
Paths.ScratchPath.Decls =
- BaseRecord->lookup(Context, Criteria.Method->getDeclName());
+ BaseRecord->lookup(Criteria.Method->getDeclName());
while (Paths.ScratchPath.Decls.first != Paths.ScratchPath.Decls.second) {
if (CXXMethodDecl *MD =
dyn_cast<CXXMethodDecl>(*Paths.ScratchPath.Decls.first)) {
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 6b812e1968de..ecfdfd7ba0b6 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -343,8 +343,8 @@ void InitListChecker::FillInValueInitializations(InitListExpr *ILE) {
if (const RecordType *RType = ILE->getType()->getAsRecordType()) {
unsigned Init = 0, NumInits = ILE->getNumInits();
for (RecordDecl::field_iterator
- Field = RType->getDecl()->field_begin(SemaRef.Context),
- FieldEnd = RType->getDecl()->field_end(SemaRef.Context);
+ Field = RType->getDecl()->field_begin(),
+ FieldEnd = RType->getDecl()->field_end();
Field != FieldEnd; ++Field) {
if (Field->isUnnamedBitfield())
continue;
@@ -449,8 +449,8 @@ int InitListChecker::numStructUnionElements(QualType DeclType) {
RecordDecl *structDecl = DeclType->getAsRecordType()->getDecl();
int InitializableMembers = 0;
for (RecordDecl::field_iterator
- Field = structDecl->field_begin(SemaRef.Context),
- FieldEnd = structDecl->field_end(SemaRef.Context);
+ Field = structDecl->field_begin(),
+ FieldEnd = structDecl->field_end();
Field != FieldEnd; ++Field) {
if ((*Field)->getIdentifier() || !(*Field)->isBitField())
++InitializableMembers;
@@ -580,7 +580,7 @@ void InitListChecker::CheckListElementTypes(InitListExpr *IList,
} else if (DeclType->isAggregateType()) {
if (DeclType->isRecordType()) {
RecordDecl *RD = DeclType->getAsRecordType()->getDecl();
- CheckStructUnionTypes(IList, DeclType, RD->field_begin(SemaRef.Context),
+ CheckStructUnionTypes(IList, DeclType, RD->field_begin(),
SubobjectIsDesignatorContext, Index,
StructuredList, StructuredIndex,
TopLevelObject);
@@ -946,7 +946,7 @@ void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
if (DeclType->isUnionType() && IList->getNumInits() == 0) {
// Value-initialize the first named member of the union.
RecordDecl *RD = DeclType->getAsRecordType()->getDecl();
- for (RecordDecl::field_iterator FieldEnd = RD->field_end(SemaRef.Context);
+ for (RecordDecl::field_iterator FieldEnd = RD->field_end();
Field != FieldEnd; ++Field) {
if (Field->getDeclName()) {
StructuredList->setInitializedFieldInUnion(*Field);
@@ -961,7 +961,7 @@ void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
// because an error should get printed out elsewhere. It might be
// worthwhile to skip over the rest of the initializer, though.
RecordDecl *RD = DeclType->getAsRecordType()->getDecl();
- RecordDecl::field_iterator FieldEnd = RD->field_end(SemaRef.Context);
+ RecordDecl::field_iterator FieldEnd = RD->field_end();
bool InitializedSomething = false;
while (Index < IList->getNumInits()) {
Expr *Init = IList->getInit(Index);
@@ -1090,9 +1090,9 @@ static void ExpandAnonymousFieldDesignator(Sema &SemaRef,
// Update FieldIter/FieldIndex;
RecordDecl *Record = cast<RecordDecl>(Path.back()->getDeclContext());
- FieldIter = Record->field_begin(SemaRef.Context);
+ FieldIter = Record->field_begin();
FieldIndex = 0;
- for (RecordDecl::field_iterator FEnd = Record->field_end(SemaRef.Context);
+ for (RecordDecl::field_iterator FEnd = Record->field_end();
FieldIter != FEnd; ++FieldIter) {
if (FieldIter->isUnnamedBitfield())
continue;
@@ -1217,8 +1217,8 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList,
IdentifierInfo *FieldName = D->getFieldName();
unsigned FieldIndex = 0;
RecordDecl::field_iterator
- Field = RT->getDecl()->field_begin(SemaRef.Context),
- FieldEnd = RT->getDecl()->field_end(SemaRef.Context);
+ Field = RT->getDecl()->field_begin(),
+ FieldEnd = RT->getDecl()->field_end();
for (; Field != FieldEnd; ++Field) {
if (Field->isUnnamedBitfield())
continue;
@@ -1235,8 +1235,7 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList,
// something that we can't designate (e.g., a member function),
// may find nothing, or may find a member of an anonymous
// struct/union.
- DeclContext::lookup_result Lookup
- = RT->getDecl()->lookup(SemaRef.Context, FieldName);
+ DeclContext::lookup_result Lookup = RT->getDecl()->lookup(FieldName);
if (Lookup.first == Lookup.second) {
// Name lookup didn't find anything.
SemaRef.Diag(D->getFieldLoc(), diag::err_field_designator_unknown)
@@ -1565,8 +1564,8 @@ InitListChecker::getStructuredSubobjectInit(InitListExpr *IList, unsigned Index,
if (RDecl->isUnion())
NumElements = 1;
else
- NumElements = std::distance(RDecl->field_begin(SemaRef.Context),
- RDecl->field_end(SemaRef.Context));
+ NumElements = std::distance(RDecl->field_begin(),
+ RDecl->field_end());
}
if (NumElements < NumInits)
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index cc9e783f6166..6f2fc5e0c434 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -65,7 +65,7 @@ void AddNamespaceUsingDirectives(ASTContext &Context,
NamespaceSet &Visited) {
DeclContext::udir_iterator I, End;
- for (llvm::tie(I, End) = NS->getUsingDirectives(Context); I !=End; ++I) {
+ for (llvm::tie(I, End) = NS->getUsingDirectives(); I !=End; ++I) {
UDirs.push_back(*I);
std::push_heap(UDirs.begin(), UDirs.end(), UsingDirAncestorCompare());
NamespaceDecl *Nominated = (*I)->getNominatedNamespace();
@@ -609,7 +609,7 @@ CppNamespaceLookup(ASTContext &Context, DeclContext *NS,
// Perform qualified name lookup into the LookupCtx.
DeclContext::lookup_iterator I, E;
- for (llvm::tie(I, E) = NS->lookup(Context, Name); I != E; ++I)
+ for (llvm::tie(I, E) = NS->lookup(Name); I != E; ++I)
if (Sema::isAcceptableLookupResult(*I, NameKind, IDNS)) {
Results.push_back(Sema::LookupResult::CreateLookupResult(Context, I, E));
break;
@@ -903,7 +903,7 @@ Sema::LookupName(Scope *S, DeclarationName Name, LookupNameKind NameKind,
continue;
}
- if ((*I)->getAttr<OverloadableAttr>(Context)) {
+ if ((*I)->getAttr<OverloadableAttr>()) {
// If this declaration has the "overloadable" attribute, we
// might have a set of overloaded functions.
@@ -1005,7 +1005,7 @@ Sema::LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name,
// Perform qualified name lookup into the LookupCtx.
DeclContext::lookup_iterator I, E;
- for (llvm::tie(I, E) = LookupCtx->lookup(Context, Name); I != E; ++I)
+ for (llvm::tie(I, E) = LookupCtx->lookup(Name); I != E; ++I)
if (isAcceptableLookupResult(*I, NameKind, IDNS))
return LookupResult::CreateLookupResult(Context, I, E);
@@ -1148,7 +1148,7 @@ Sema::LookupParsedName(Scope *S, const CXXScopeSpec *SS,
// (C++0x [temp.dep.type]).
unsigned IDNS = getIdentifierNamespacesFromLookupNameKind(NameKind, true);
DeclContext::lookup_iterator I, E;
- for (llvm::tie(I, E) = Current->lookup(Context, Name); I != E; ++I)
+ for (llvm::tie(I, E) = Current->lookup(Name); I != E; ++I)
if (isAcceptableLookupResult(*I, NameKind, IDNS))
return LookupResult::CreateLookupResult(Context, I, E);
}
@@ -1604,9 +1604,17 @@ void Sema::LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
for (LookupResult::iterator Op = Operators.begin(), OpEnd = Operators.end();
Op != OpEnd; ++Op) {
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Op))
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Op)) {
if (IsAcceptableNonMemberOperatorCandidate(FD, T1, T2, Context))
Functions.insert(FD); // FIXME: canonical FD
+ } else if (FunctionTemplateDecl *FunTmpl
+ = dyn_cast<FunctionTemplateDecl>(*Op)) {
+ // FIXME: friend operators?
+ // FIXME: do we need to check IsAcceptableNonMemberOperatorCandidate,
+ // later?
+ if (!FunTmpl->getDeclContext()->isRecord())
+ Functions.insert(FunTmpl);
+ }
}
}
@@ -1648,25 +1656,23 @@ void Sema::ArgumentDependentLookup(DeclarationName Name,
// namespaces even if they are not visible during an ordinary
// lookup (11.4).
DeclContext::lookup_iterator I, E;
- for (llvm::tie(I, E) = (*NS)->lookup(Context, Name); I != E; ++I) {
- FunctionDecl *Func = dyn_cast<FunctionDecl>(*I);
- if (!Func)
- break;
-
- Functions.insert(Func);
+ for (llvm::tie(I, E) = (*NS)->lookup(Name); I != E; ++I) {
+ if (FunctionDecl *Func = dyn_cast<FunctionDecl>(*I))
+ Functions.insert(Func);
+ else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(*I))
+ Functions.insert(FunTmpl);
}
}
if (GlobalScope) {
DeclContext::lookup_iterator I, E;
for (llvm::tie(I, E)
- = Context.getTranslationUnitDecl()->lookup(Context, Name);
+ = Context.getTranslationUnitDecl()->lookup(Name);
I != E; ++I) {
- FunctionDecl *Func = dyn_cast<FunctionDecl>(*I);
- if (!Func)
- break;
-
- Functions.insert(Func);
+ if (FunctionDecl *Func = dyn_cast<FunctionDecl>(*I))
+ Functions.insert(Func);
+ else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(*I))
+ Functions.insert(FunTmpl);
}
}
}
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index fcc155750cdc..03ac2d9bb73a 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -1375,7 +1375,7 @@ bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
Context.getCanonicalType(ToType).getUnqualifiedType());
DeclContext::lookup_iterator Con, ConEnd;
for (llvm::tie(Con, ConEnd)
- = ToRecordDecl->lookup(Context, ConstructorName);
+ = ToRecordDecl->lookup(ConstructorName);
Con != ConEnd; ++Con) {
CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
if (Constructor->isConvertingConstructor())
@@ -2161,9 +2161,16 @@ void Sema::AddFunctionCandidates(const FunctionSet &Functions,
bool SuppressUserConversions) {
for (FunctionSet::const_iterator F = Functions.begin(),
FEnd = Functions.end();
- F != FEnd; ++F)
- AddOverloadCandidate(*F, Args, NumArgs, CandidateSet,
- SuppressUserConversions);
+ F != FEnd; ++F) {
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*F))
+ AddOverloadCandidate(FD, Args, NumArgs, CandidateSet,
+ SuppressUserConversions);
+ else
+ AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*F),
+ /*FIXME: explicit args */false, 0, 0,
+ Args, NumArgs, CandidateSet,
+ SuppressUserConversions);
+ }
}
/// AddMethodCandidate - Adds the given C++ member function to the set
@@ -2267,6 +2274,9 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, Expr *Object,
/// template specialization.
void
Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
+ bool HasExplicitTemplateArgs,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions,
@@ -2283,8 +2293,9 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
TemplateDeductionInfo Info(Context);
FunctionDecl *Specialization = 0;
if (TemplateDeductionResult Result
- = DeduceTemplateArguments(FunctionTemplate, Args, NumArgs,
- Specialization, Info)) {
+ = DeduceTemplateArguments(FunctionTemplate, HasExplicitTemplateArgs,
+ ExplicitTemplateArgs, NumExplicitTemplateArgs,
+ Args, NumArgs, Specialization, Info)) {
// FIXME: Record what happened with template argument deduction, so
// that we can give the user a beautiful diagnostic.
(void)Result;
@@ -2510,7 +2521,7 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op,
// FIXME: Lookup in base classes, too!
if (const RecordType *T1Rec = T1->getAsRecordType()) {
DeclContext::lookup_const_iterator Oper, OperEnd;
- for (llvm::tie(Oper, OperEnd) = T1Rec->getDecl()->lookup(Context, OpName);
+ for (llvm::tie(Oper, OperEnd) = T1Rec->getDecl()->lookup(OpName);
Oper != OperEnd; ++Oper)
AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Args[0],
Args+1, NumArgs - 1, CandidateSet,
@@ -3405,8 +3416,11 @@ Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
CandEnd = CandidateSet.end();
Cand != CandEnd; ++Cand)
- if (Cand->Function)
+ if (Cand->Function) {
Functions.insert(Cand->Function);
+ if (FunctionTemplateDecl *FunTmpl = Cand->Function->getPrimaryTemplate())
+ Functions.insert(FunTmpl);
+ }
ArgumentDependentLookup(Name, Args, NumArgs, Functions);
@@ -3415,15 +3429,24 @@ Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
CandEnd = CandidateSet.end();
Cand != CandEnd; ++Cand)
- if (Cand->Function)
+ if (Cand->Function) {
Functions.erase(Cand->Function);
+ if (FunctionTemplateDecl *FunTmpl = Cand->Function->getPrimaryTemplate())
+ Functions.erase(FunTmpl);
+ }
// For each of the ADL candidates we found, add it to the overload
// set.
for (FunctionSet::iterator Func = Functions.begin(),
FuncEnd = Functions.end();
- Func != FuncEnd; ++Func)
- AddOverloadCandidate(*Func, Args, NumArgs, CandidateSet);
+ Func != FuncEnd; ++Func) {
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Func))
+ AddOverloadCandidate(FD, Args, NumArgs, CandidateSet);
+ else
+ AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*Func),
+ /*FIXME: explicit args */false, 0, 0,
+ Args, NumArgs, CandidateSet);
+ }
}
/// isBetterOverloadCandidate - Determines whether the first overload
@@ -3556,7 +3579,7 @@ Sema::BestViableFunction(OverloadCandidateSet& CandidateSet,
// Best is the best viable function.
if (Best->Function &&
(Best->Function->isDeleted() ||
- Best->Function->getAttr<UnavailableAttr>(Context)))
+ Best->Function->getAttr<UnavailableAttr>()))
return OR_Deleted;
// C++ [basic.def.odr]p2:
@@ -3583,7 +3606,7 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
if (Cand->Viable || !OnlyViable) {
if (Cand->Function) {
if (Cand->Function->isDeleted() ||
- Cand->Function->getAttr<UnavailableAttr>(Context)) {
+ Cand->Function->getAttr<UnavailableAttr>()) {
// Deleted or "unavailable" function.
Diag(Cand->Function->getLocation(), diag::err_ovl_candidate_deleted)
<< Cand->Function->isDeleted();
@@ -3741,6 +3764,9 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
/// arguments and Fn, and returns NULL.
FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
DeclarationName UnqualifiedName,
+ bool HasExplicitTemplateArgs,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
SourceLocation LParenLoc,
Expr **Args, unsigned NumArgs,
SourceLocation *CommaLocs,
@@ -3773,11 +3799,17 @@ FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
Func != FuncEnd; ++Func) {
DeclContext *Ctx = 0;
if (FunctionDecl *FunDecl = dyn_cast<FunctionDecl>(*Func)) {
+ if (HasExplicitTemplateArgs)
+ continue;
+
AddOverloadCandidate(FunDecl, Args, NumArgs, CandidateSet);
Ctx = FunDecl->getDeclContext();
} else {
FunctionTemplateDecl *FunTmpl = cast<FunctionTemplateDecl>(*Func);
- AddTemplateOverloadCandidate(FunTmpl, Args, NumArgs, CandidateSet);
+ AddTemplateOverloadCandidate(FunTmpl, HasExplicitTemplateArgs,
+ ExplicitTemplateArgs,
+ NumExplicitTemplateArgs,
+ Args, NumArgs, CandidateSet);
Ctx = FunTmpl->getDeclContext();
}
@@ -3786,6 +3818,7 @@ FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
ArgumentDependentLookup = false;
}
} else if (FunctionDecl *Func = dyn_cast_or_null<FunctionDecl>(Callee)) {
+ assert(!HasExplicitTemplateArgs && "Explicit template arguments?");
AddOverloadCandidate(Func, Args, NumArgs, CandidateSet);
if (Func->getDeclContext()->isRecord() ||
@@ -3793,7 +3826,10 @@ FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
ArgumentDependentLookup = false;
} else if (FunctionTemplateDecl *FuncTemplate
= dyn_cast_or_null<FunctionTemplateDecl>(Callee)) {
- AddTemplateOverloadCandidate(FuncTemplate, Args, NumArgs, CandidateSet);
+ AddTemplateOverloadCandidate(FuncTemplate, HasExplicitTemplateArgs,
+ ExplicitTemplateArgs,
+ NumExplicitTemplateArgs,
+ Args, NumArgs, CandidateSet);
if (FuncTemplate->getDeclContext()->isRecord())
ArgumentDependentLookup = false;
@@ -3802,6 +3838,7 @@ FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
if (Callee)
UnqualifiedName = Callee->getDeclName();
+ // FIXME: Pass explicit template arguments through for ADL
if (ArgumentDependentLookup)
AddArgumentDependentLookupCandidates(UnqualifiedName, Args, NumArgs,
CandidateSet);
@@ -4273,7 +4310,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
OverloadCandidateSet CandidateSet;
DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Call);
DeclContext::lookup_const_iterator Oper, OperEnd;
- for (llvm::tie(Oper, OperEnd) = Record->getDecl()->lookup(Context, OpName);
+ for (llvm::tie(Oper, OperEnd) = Record->getDecl()->lookup(OpName);
Oper != OperEnd; ++Oper)
AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Object, Args, NumArgs,
CandidateSet, /*SuppressUserConversions=*/false);
@@ -4477,8 +4514,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc,
DeclContext::lookup_const_iterator Oper, OperEnd;
for (llvm::tie(Oper, OperEnd)
- = BaseRecord->getDecl()->lookup(Context, OpName);
- Oper != OperEnd; ++Oper)
+ = BaseRecord->getDecl()->lookup(OpName); Oper != OperEnd; ++Oper)
AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Base, 0, 0, CandidateSet,
/*SuppressUserConversions=*/false);
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 914839cbf790..63191e0e00cc 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -84,7 +84,7 @@ Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
SourceLocation Loc;
SourceRange R1, R2;
- if (!E->isUnusedResultAWarning(Loc, R1, R2, Context))
+ if (!E->isUnusedResultAWarning(Loc, R1, R2))
continue;
Diag(Loc, diag::warn_unused_expr) << R1 << R2;
@@ -766,7 +766,7 @@ Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
}
QualType FnRetType = CurBlock->ReturnType;
- if (CurBlock->TheDecl->hasAttr<NoReturnAttr>(Context)) {
+ if (CurBlock->TheDecl->hasAttr<NoReturnAttr>()) {
Diag(ReturnLoc, diag::err_noreturn_block_has_return_expr)
<< getCurFunctionOrMethodDecl()->getDeclName();
return StmtError();
@@ -842,7 +842,7 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, FullExprArg rex) {
QualType FnRetType;
if (const FunctionDecl *FD = getCurFunctionDecl()) {
FnRetType = FD->getResultType();
- if (FD->hasAttr<NoReturnAttr>(Context))
+ if (FD->hasAttr<NoReturnAttr>())
Diag(ReturnLoc, diag::warn_noreturn_function_has_return_expr)
<< getCurFunctionOrMethodDecl()->getDeclName();
} else if (ObjCMethodDecl *MD = getCurMethodDecl())
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index cd985c536c77..568d68c9a7e8 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -852,7 +852,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
NumTemplateArgs);
if (CheckTemplateArgumentList(Template, TemplateLoc, LAngleLoc,
TemplateArgs, NumTemplateArgs, RAngleLoc,
- Converted))
+ false, Converted))
return QualType();
assert((Converted.structuredSize() ==
@@ -933,6 +933,42 @@ Sema::ActOnTemplateIdType(TemplateTy TemplateD, SourceLocation TemplateLoc,
return Result.getAsOpaquePtr();
}
+Sema::OwningExprResult Sema::BuildTemplateIdExpr(TemplateName Template,
+ SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc,
+ const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs,
+ SourceLocation RAngleLoc) {
+ // FIXME: Can we do any checking at this point? I guess we could check the
+ // template arguments that we have against the template name, if the template
+ // name refers to a single template. That's not a terribly common case,
+ // though.
+ return Owned(TemplateIdRefExpr::Create(Context,
+ /*FIXME: New type?*/Context.OverloadTy,
+ /*FIXME: Necessary?*/0,
+ /*FIXME: Necessary?*/SourceRange(),
+ Template, TemplateNameLoc, LAngleLoc,
+ TemplateArgs,
+ NumTemplateArgs, RAngleLoc));
+}
+
+Sema::OwningExprResult Sema::ActOnTemplateIdExpr(TemplateTy TemplateD,
+ SourceLocation TemplateNameLoc,
+ SourceLocation LAngleLoc,
+ ASTTemplateArgsPtr TemplateArgsIn,
+ SourceLocation *TemplateArgLocs,
+ SourceLocation RAngleLoc) {
+ TemplateName Template = TemplateD.getAsVal<TemplateName>();
+
+ // Translate the parser's template argument list in our AST format.
+ llvm::SmallVector<TemplateArgument, 16> TemplateArgs;
+ translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
+
+ return BuildTemplateIdExpr(Template, TemplateNameLoc, LAngleLoc,
+ TemplateArgs.data(), TemplateArgs.size(),
+ RAngleLoc);
+}
+
/// \brief Form a dependent template name.
///
/// This action forms a dependent template name given the template
@@ -1019,6 +1055,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation RAngleLoc,
+ bool PartialTemplateArgs,
TemplateArgumentListBuilder &Converted) {
TemplateParameterList *Params = Template->getTemplateParameters();
unsigned NumParams = Params->size();
@@ -1029,7 +1066,8 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
NumParams > 0 && Params->getParam(NumParams - 1)->isTemplateParameterPack();
if ((NumArgs > NumParams && !HasParameterPack) ||
- NumArgs < Params->getMinRequiredArguments()) {
+ (NumArgs < Params->getMinRequiredArguments() &&
+ !PartialTemplateArgs)) {
// FIXME: point at either the first arg beyond what we can handle,
// or the '>', depending on whether we have too many or too few
// arguments.
@@ -1056,6 +1094,9 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
for (TemplateParameterList::iterator Param = Params->begin(),
ParamEnd = Params->end();
Param != ParamEnd; ++Param, ++ArgIdx) {
+ if (ArgIdx > NumArgs && PartialTemplateArgs)
+ break;
+
// Decode the template argument
TemplateArgument Arg;
if (ArgIdx >= NumArgs) {
@@ -2302,7 +2343,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
TemplateArgs.size());
if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, LAngleLoc,
TemplateArgs.data(), TemplateArgs.size(),
- RAngleLoc, Converted))
+ RAngleLoc, false, Converted))
return true;
assert((Converted.structuredSize() ==
@@ -2498,7 +2539,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
// Add the specialization into its lexical context, so that it can
// be seen when iterating through the list of declarations in that
// context. However, specializations are not found by name lookup.
- CurContext->addDecl(Context, Specialization);
+ CurContext->addDecl(Specialization);
return DeclPtrTy::make(Specialization);
}
@@ -2597,7 +2638,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,
TemplateArgs.size());
if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, LAngleLoc,
TemplateArgs.data(), TemplateArgs.size(),
- RAngleLoc, Converted))
+ RAngleLoc, false, Converted))
return true;
assert((Converted.structuredSize() ==
@@ -2654,7 +2695,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,
ClassTemplate,
Converted, 0);
Specialization->setLexicalDeclContext(CurContext);
- CurContext->addDecl(Context, Specialization);
+ CurContext->addDecl(Specialization);
return DeclPtrTy::make(Specialization);
}
@@ -2703,7 +2744,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,
// since explicit instantiations are never found by name lookup, we
// just put it into the declaration context directly.
Specialization->setLexicalDeclContext(CurContext);
- CurContext->addDecl(Context, Specialization);
+ CurContext->addDecl(Specialization);
// C++ [temp.explicit]p3:
// A definition of a class template or class member template
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index 3d909bb26a79..5a0578f6bcb7 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -868,6 +868,16 @@ static bool isSimpleTemplateIdType(QualType T) {
/// \param FunctionTemplate the function template for which we are performing
/// template argument deduction.
///
+/// \param HasExplicitTemplateArgs whether any template arguments were
+/// explicitly specified.
+///
+/// \param ExplicitTemplateArguments when @p HasExplicitTemplateArgs is true,
+/// the explicitly-specified template arguments.
+///
+/// \param NumExplicitTemplateArguments when @p HasExplicitTemplateArgs is true,
+/// the number of explicitly-specified template arguments in
+/// @p ExplicitTemplateArguments. This value may be zero.
+///
/// \param Args the function call arguments
///
/// \param NumArgs the number of arguments in Args
@@ -880,22 +890,22 @@ static bool isSimpleTemplateIdType(QualType T) {
/// about template argument deduction.
///
/// \returns the result of template argument deduction.
-///
-/// FIXME: We will also need to pass in any explicitly-specified template
-/// arguments.
Sema::TemplateDeductionResult
Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
+ bool HasExplicitTemplateArgs,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
Expr **Args, unsigned NumArgs,
FunctionDecl *&Specialization,
TemplateDeductionInfo &Info) {
FunctionDecl *Function = FunctionTemplate->getTemplatedDecl();
-
+
// C++ [temp.deduct.call]p1:
// Template argument deduction is done by comparing each function template
// parameter type (call it P) with the type of the corresponding argument
// of the call (call it A) as described below.
unsigned CheckArgs = NumArgs;
- if (NumArgs < Function->getNumParams())
+ if (NumArgs < Function->getMinRequiredArguments())
return TDK_TooFewArguments;
else if (NumArgs > Function->getNumParams()) {
const FunctionProtoType *Proto
@@ -905,18 +915,87 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
CheckArgs = Function->getNumParams();
}
-
+
// Template argument deduction for function templates in a SFINAE context.
// Trap any errors that might occur.
SFINAETrap Trap(*this);
-
- // Deduce template arguments from the function parameters.
- llvm::SmallVector<TemplateArgument, 4> Deduced;
- Deduced.resize(FunctionTemplate->getTemplateParameters()->size());
+
+ // The types of the parameters from which we will perform template argument
+ // deduction.
TemplateParameterList *TemplateParams
= FunctionTemplate->getTemplateParameters();
+ llvm::SmallVector<TemplateArgument, 4> Deduced;
+ llvm::SmallVector<QualType, 4> ParamTypes;
+ if (NumExplicitTemplateArgs) {
+ // C++ [temp.arg.explicit]p3:
+ // Template arguments that are present shall be specified in the
+ // declaration order of their corresponding template-parameters. The
+ // template argument list shall not specify more template-arguments than
+ // there are corresponding template-parameters.
+ TemplateArgumentListBuilder Builder(TemplateParams,
+ NumExplicitTemplateArgs);
+
+ // Enter a new template instantiation context where we check the
+ // explicitly-specified template arguments against this function template,
+ // and then substitute them into the function parameter types.
+ InstantiatingTemplate Inst(*this, FunctionTemplate->getLocation(),
+ FunctionTemplate, Deduced.data(), Deduced.size(),
+ ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution);
+ if (Inst)
+ return TDK_InstantiationDepth;
+
+ if (CheckTemplateArgumentList(FunctionTemplate,
+ SourceLocation(), SourceLocation(),
+ ExplicitTemplateArgs,
+ NumExplicitTemplateArgs,
+ SourceLocation(),
+ true,
+ Builder) || Trap.hasErrorOccurred())
+ return TDK_InvalidExplicitArguments;
+
+ // Form the template argument list from the explicitly-specified
+ // template arguments.
+ TemplateArgumentList *ExplicitArgumentList
+ = new (Context) TemplateArgumentList(Context, Builder, /*TakeArgs=*/true);
+ Info.reset(ExplicitArgumentList);
+
+ // Instantiate the types of each of the function parameters given the
+ // explicitly-specified template arguments.
+ for (FunctionDecl::param_iterator P = Function->param_begin(),
+ PEnd = Function->param_end();
+ P != PEnd;
+ ++P) {
+ QualType ParamType = InstantiateType((*P)->getType(),
+ *ExplicitArgumentList,
+ (*P)->getLocation(),
+ (*P)->getDeclName());
+ if (ParamType.isNull() || Trap.hasErrorOccurred())
+ return TDK_SubstitutionFailure;
+
+ ParamTypes.push_back(ParamType);
+ }
+
+ // C++ [temp.arg.explicit]p2:
+ // Trailing template arguments that can be deduced (14.8.2) may be
+ // omitted from the list of explicit template- arguments. If all of the
+ // template arguments can be deduced, they may all be omitted; in this
+ // case, the empty template argument list <> itself may also be omitted.
+ //
+ // Take all of the explicitly-specified arguments and put them into the
+ // set of deduced template arguments.
+ Deduced.reserve(TemplateParams->size());
+ for (unsigned I = 0, N = ExplicitArgumentList->size(); I != N; ++I)
+ Deduced.push_back(ExplicitArgumentList->get(I));
+ } else {
+ // Just fill in the parameter types from the function declaration.
+ for (unsigned I = 0; I != CheckArgs; ++I)
+ ParamTypes.push_back(Function->getParamDecl(I)->getType());
+ }
+
+ // Deduce template arguments from the function parameters.
+ Deduced.resize(TemplateParams->size());
for (unsigned I = 0; I != CheckArgs; ++I) {
- QualType ParamType = Function->getParamDecl(I)->getType();
+ QualType ParamType = ParamTypes[I];
QualType ArgType = Args[I]->getType();
// C++ [temp.deduct.call]p2:
@@ -998,11 +1077,6 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
// FIXME: C++ [temp.deduct.call] paragraphs 6-9 deal with function
// pointer parameters.
}
-
- InstantiatingTemplate Inst(*this, FunctionTemplate->getLocation(),
- FunctionTemplate, Deduced.data(), Deduced.size());
- if (Inst)
- return TDK_InstantiationDepth;
// C++ [temp.deduct.type]p2:
// [...] or if any template argument remains neither deduced nor
@@ -1030,20 +1104,36 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate,
= new (Context) TemplateArgumentList(Context, Builder, /*TakeArgs=*/true);
Info.reset(DeducedArgumentList);
+ // Enter a new template instantiation context while we instantiate the
+ // actual function declaration.
+ InstantiatingTemplate Inst(*this, FunctionTemplate->getLocation(),
+ FunctionTemplate, Deduced.data(), Deduced.size(),
+ ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution);
+ if (Inst)
+ return TDK_InstantiationDepth;
+
// Substitute the deduced template arguments into the function template
// declaration to produce the function template specialization.
Specialization = cast_or_null<FunctionDecl>(
InstantiateDecl(FunctionTemplate->getTemplatedDecl(),
FunctionTemplate->getDeclContext(),
*DeducedArgumentList));
+ if (!Specialization)
+ return TDK_SubstitutionFailure;
- if (!Specialization || Trap.hasErrorOccurred())
+ // If the template argument list is owned by the function template
+ // specialization, release it.
+ if (Specialization->getTemplateSpecializationArgs() == DeducedArgumentList)
+ Info.take();
+
+ // There may have been an error that did not prevent us from constructing a
+ // declaration. Mark the declaration invalid and return with a substitution
+ // failure.
+ if (Trap.hasErrorOccurred()) {
+ Specialization->setInvalidDecl(true);
return TDK_SubstitutionFailure;
-
- // Turn the specialization into an actual function template specialization.
- Specialization->setFunctionTemplateSpecialization(Context,
- FunctionTemplate,
- Info.take());
+ }
+
return TDK_Success;
}
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index aed348966a4f..6c2dc77b4cce 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -100,6 +100,30 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
SourceLocation PointOfInstantiation,
+ FunctionTemplateDecl *FunctionTemplate,
+ const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs,
+ ActiveTemplateInstantiation::InstantiationKind Kind,
+ SourceRange InstantiationRange)
+: SemaRef(SemaRef) {
+
+ Invalid = CheckInstantiationDepth(PointOfInstantiation,
+ InstantiationRange);
+ if (!Invalid) {
+ ActiveTemplateInstantiation Inst;
+ Inst.Kind = Kind;
+ Inst.PointOfInstantiation = PointOfInstantiation;
+ Inst.Entity = reinterpret_cast<uintptr_t>(FunctionTemplate);
+ Inst.TemplateArgs = TemplateArgs;
+ Inst.NumTemplateArgs = NumTemplateArgs;
+ Inst.InstantiationRange = InstantiationRange;
+ SemaRef.ActiveTemplateInstantiations.push_back(Inst);
+ Invalid = false;
+ }
+}
+
+Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
+ SourceLocation PointOfInstantiation,
ClassTemplatePartialSpecializationDecl *PartialSpec,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs,
@@ -111,7 +135,7 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
if (!Invalid) {
ActiveTemplateInstantiation Inst;
Inst.Kind
- = ActiveTemplateInstantiation::PartialSpecDeductionInstantiation;
+ = ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution;
Inst.PointOfInstantiation = PointOfInstantiation;
Inst.Entity = reinterpret_cast<uintptr_t>(PartialSpec);
Inst.TemplateArgs = TemplateArgs;
@@ -148,6 +172,7 @@ bool Sema::InstantiatingTemplate::CheckInstantiationDepth(
/// \brief Prints the current instantiation stack through a series of
/// notes.
void Sema::PrintInstantiationStack() {
+ // FIXME: In all of these cases, we need to show the template arguments
for (llvm::SmallVector<ActiveTemplateInstantiation, 16>::reverse_iterator
Active = ActiveTemplateInstantiations.rbegin(),
ActiveEnd = ActiveTemplateInstantiations.rend();
@@ -183,7 +208,7 @@ void Sema::PrintInstantiationStack() {
TemplateDecl *Template = cast<TemplateDecl>((Decl *)Active->Entity);
std::string TemplateArgsStr
= TemplateSpecializationType::PrintTemplateArgumentList(
- Active->TemplateArgs,
+ Active->TemplateArgs,
Active->NumTemplateArgs,
Context.PrintingPolicy);
Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
@@ -193,18 +218,31 @@ void Sema::PrintInstantiationStack() {
break;
}
- case ActiveTemplateInstantiation::PartialSpecDeductionInstantiation: {
- ClassTemplatePartialSpecializationDecl *PartialSpec
- = cast<ClassTemplatePartialSpecializationDecl>((Decl *)Active->Entity);
- // FIXME: The active template instantiation's template arguments
- // are interesting, too. We should add something like [with T =
- // foo, U = bar, etc.] to the string.
+ case ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution: {
+ FunctionTemplateDecl *FnTmpl
+ = cast<FunctionTemplateDecl>((Decl *)Active->Entity);
Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
- diag::note_partial_spec_deduct_instantiation_here)
- << Context.getTypeDeclType(PartialSpec)
- << Active->InstantiationRange;
+ diag::note_explicit_template_arg_substitution_here)
+ << FnTmpl << Active->InstantiationRange;
break;
}
+
+ case ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution:
+ if (ClassTemplatePartialSpecializationDecl *PartialSpec
+ = dyn_cast<ClassTemplatePartialSpecializationDecl>(
+ (Decl *)Active->Entity)) {
+ Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+ diag::note_partial_spec_deduct_instantiation_here)
+ << Context.getTypeDeclType(PartialSpec)
+ << Active->InstantiationRange;
+ } else {
+ FunctionTemplateDecl *FnTmpl
+ = cast<FunctionTemplateDecl>((Decl *)Active->Entity);
+ Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+ diag::note_function_template_deduction_instantiation_here)
+ << FnTmpl << Active->InstantiationRange;
+ }
+ break;
}
}
@@ -219,19 +257,20 @@ bool Sema::isSFINAEContext() const {
++Active) {
switch(Active->Kind) {
- case ActiveTemplateInstantiation::PartialSpecDeductionInstantiation:
- // We're in a template argument deduction context, so SFINAE
- // applies.
- return true;
-
+ case ActiveTemplateInstantiation::TemplateInstantiation:
+ // This is a template instantiation, so there is no SFINAE.
+ return false;
+
case ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation:
// A default template argument instantiation may or may not be a
// SFINAE context; look further up the stack.
break;
-
- case ActiveTemplateInstantiation::TemplateInstantiation:
- // This is a template instantiation, so there is no SFINAE.
- return false;
+
+ case ActiveTemplateInstantiation::ExplicitTemplateArgumentSubstitution:
+ case ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution:
+ // We're either substitution explicitly-specified template arguments
+ // or deduced template arguments, so SFINAE applies.
+ return true;
}
}
@@ -530,7 +569,7 @@ TemplateTypeInstantiator::InstantiateTypeOfExprType(
if (E.isInvalid())
return QualType();
- return SemaRef.Context.getTypeOfExprType(E.takeAs<Expr>());
+ return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
}
QualType
@@ -555,7 +594,7 @@ TemplateTypeInstantiator::InstantiateDecltypeType(const DecltypeType *T) const {
if (E.isInvalid())
return QualType();
- return SemaRef.Context.getDecltypeType(E.takeAs<Expr>());
+ return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
}
QualType
@@ -584,6 +623,15 @@ InstantiateTemplateTypeParmType(const TemplateTypeParmType *T) const {
if (T->getDepth() == 0) {
// Replace the template type parameter with its corresponding
// template argument.
+
+ // If the corresponding template argument is NULL or doesn't exist, it's
+ // because we are performing instantiation from explicitly-specified
+ // template arguments in a function template class, but there were some
+ // arguments left unspecified.
+ if (T->getIndex() >= TemplateArgs.size() ||
+ TemplateArgs[T->getIndex()].isNull())
+ return QualType(T, 0); // Would be nice to keep the original type here
+
assert(TemplateArgs[T->getIndex()].getKind() == TemplateArgument::Type &&
"Template argument kind mismatch");
return TemplateArgs[T->getIndex()].getAsType();
@@ -859,8 +907,8 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
Invalid = true;
llvm::SmallVector<DeclPtrTy, 4> Fields;
- for (RecordDecl::decl_iterator Member = Pattern->decls_begin(Context),
- MemberEnd = Pattern->decls_end(Context);
+ for (RecordDecl::decl_iterator Member = Pattern->decls_begin(),
+ MemberEnd = Pattern->decls_end();
Member != MemberEnd; ++Member) {
Decl *NewMember = InstantiateDecl(*Member, Instantiation, TemplateArgs);
if (NewMember) {
@@ -996,11 +1044,11 @@ void
Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
CXXRecordDecl *Instantiation,
const TemplateArgumentList &TemplateArgs) {
- for (DeclContext::decl_iterator D = Instantiation->decls_begin(Context),
- DEnd = Instantiation->decls_end(Context);
+ for (DeclContext::decl_iterator D = Instantiation->decls_begin(),
+ DEnd = Instantiation->decls_end();
D != DEnd; ++D) {
if (FunctionDecl *Function = dyn_cast<FunctionDecl>(*D)) {
- if (!Function->getBody(Context))
+ if (!Function->getBody())
InstantiateFunctionDefinition(PointOfInstantiation, Function);
} else if (VarDecl *Var = dyn_cast<VarDecl>(*D)) {
const VarDecl *Def = 0;
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index a05095fa57a6..f59719992066 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -98,7 +98,7 @@ Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {
if (Invalid)
Typedef->setInvalidDecl();
- Owner->addDecl(SemaRef.Context, Typedef);
+ Owner->addDecl(Typedef);
return Typedef;
}
@@ -124,7 +124,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
// are not static data members.
bool Redeclaration = false;
SemaRef.CheckVariableDeclaration(Var, 0, Redeclaration);
- Owner->addDecl(SemaRef.Context, Var);
+ Owner->addDecl(Var);
if (D->getInit()) {
OwningExprResult Init
@@ -188,7 +188,7 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
if (Invalid)
Field->setInvalidDecl();
- Owner->addDecl(SemaRef.Context, Field);
+ Owner->addDecl(Field);
}
return Field;
@@ -219,14 +219,14 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
/*PrevDecl=*/0);
Enum->setInstantiationOfMemberEnum(D);
Enum->setAccess(D->getAccess());
- Owner->addDecl(SemaRef.Context, Enum);
+ Owner->addDecl(Enum);
Enum->startDefinition();
llvm::SmallVector<Sema::DeclPtrTy, 4> Enumerators;
EnumConstantDecl *LastEnumConst = 0;
- for (EnumDecl::enumerator_iterator EC = D->enumerator_begin(SemaRef.Context),
- ECEnd = D->enumerator_end(SemaRef.Context);
+ for (EnumDecl::enumerator_iterator EC = D->enumerator_begin(),
+ ECEnd = D->enumerator_end();
EC != ECEnd; ++EC) {
// The specified value for the enumerator.
OwningExprResult Value = SemaRef.Owned((Expr *)0);
@@ -257,7 +257,7 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
}
if (EnumConst) {
- Enum->addDecl(SemaRef.Context, EnumConst);
+ Enum->addDecl(EnumConst);
Enumerators.push_back(Sema::DeclPtrTy::make(EnumConst));
LastEnumConst = EnumConst;
}
@@ -289,12 +289,29 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
if (!D->isInjectedClassName())
Record->setInstantiationOfMemberClass(D);
- Owner->addDecl(SemaRef.Context, Record);
+ Owner->addDecl(Record);
return Record;
}
Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D) {
- // FIXME: Look for existing specializations (explicit or otherwise).
+ // Check whether there is already a function template specialization for
+ // this declaration.
+ FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate();
+ void *InsertPos = 0;
+ if (FunctionTemplate) {
+ llvm::FoldingSetNodeID ID;
+ FunctionTemplateSpecializationInfo::Profile(ID,
+ TemplateArgs.getFlatArgumentList(),
+ TemplateArgs.flat_size());
+
+ FunctionTemplateSpecializationInfo *Info
+ = FunctionTemplate->getSpecializations().FindNodeOrInsertPos(ID,
+ InsertPos);
+
+ // If we already have a function template specialization, return it.
+ if (Info)
+ return Info->Function;
+ }
Sema::LocalInstantiationScope Scope(SemaRef);
@@ -325,10 +342,15 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D) {
NamedDecl *PrevDecl = 0;
SemaRef.CheckFunctionDeclaration(Function, PrevDecl, Redeclaration,
/*FIXME:*/OverloadableAttrRequired);
-
- // FIXME: link this to the function template from which it was instantiated.
-
+ if (FunctionTemplate) {
+ // Record this function template specialization.
+ Function->setFunctionTemplateSpecialization(SemaRef.Context,
+ FunctionTemplate,
+ &TemplateArgs,
+ InsertPos);
+ }
+
return Function;
}
@@ -372,7 +394,7 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) {
/*FIXME:*/OverloadableAttrRequired);
if (!Method->isInvalidDecl() || !PrevDecl)
- Owner->addDecl(SemaRef.Context, Method);
+ Owner->addDecl(Method);
return Method;
}
@@ -420,7 +442,7 @@ Decl *TemplateDeclInstantiator::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
/*FIXME:*/OverloadableAttrRequired);
Record->addedConstructor(SemaRef.Context, Constructor);
- Owner->addDecl(SemaRef.Context, Constructor);
+ Owner->addDecl(Constructor);
return Constructor;
}
@@ -452,7 +474,7 @@ Decl *TemplateDeclInstantiator::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
NamedDecl *PrevDecl = 0;
SemaRef.CheckFunctionDeclaration(Destructor, PrevDecl, Redeclaration,
/*FIXME:*/OverloadableAttrRequired);
- Owner->addDecl(SemaRef.Context, Destructor);
+ Owner->addDecl(Destructor);
return Destructor;
}
@@ -485,7 +507,7 @@ Decl *TemplateDeclInstantiator::VisitCXXConversionDecl(CXXConversionDecl *D) {
NamedDecl *PrevDecl = 0;
SemaRef.CheckFunctionDeclaration(Conversion, PrevDecl, Redeclaration,
/*FIXME:*/OverloadableAttrRequired);
- Owner->addDecl(SemaRef.Context, Conversion);
+ Owner->addDecl(Conversion);
return Conversion;
}
@@ -606,6 +628,28 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,
FunctionDecl *Tmpl) {
if (Tmpl->isDeleted())
New->setDeleted();
+
+ // If we are performing substituting explicitly-specified template arguments
+ // or deduced template arguments into a function template and we reach this
+ // point, we are now past the point where SFINAE applies and have committed
+ // to keeping the new function template specialization. We therefore
+ // convert the active template instantiation for the function template
+ // into a template instantiation for this specific function template
+ // specialization, which is not a SFINAE context, so that we diagnose any
+ // further errors in the declaration itself.
+ typedef Sema::ActiveTemplateInstantiation ActiveInstType;
+ ActiveInstType &ActiveInst = SemaRef.ActiveTemplateInstantiations.back();
+ if (ActiveInst.Kind == ActiveInstType::ExplicitTemplateArgumentSubstitution ||
+ ActiveInst.Kind == ActiveInstType::DeducedTemplateArgumentSubstitution) {
+ if (FunctionTemplateDecl *FunTmpl
+ = dyn_cast<FunctionTemplateDecl>((Decl *)ActiveInst.Entity)) {
+ assert(FunTmpl->getTemplatedDecl() == Tmpl &&
+ "Deduction from the wrong function template?");
+ ActiveInst.Kind = ActiveInstType::TemplateInstantiation;
+ ActiveInst.Entity = reinterpret_cast<uintptr_t>(New);
+ }
+ }
+
return false;
}
@@ -641,14 +685,23 @@ TemplateDeclInstantiator::InitMethodInstantiation(CXXMethodDecl *New,
/// \brief Instantiate the definition of the given function from its
/// template.
///
+/// \param PointOfInstantiation the point at which the instantiation was
+/// required. Note that this is not precisely a "point of instantiation"
+/// for the function, but it's close.
+///
/// \param Function the already-instantiated declaration of a
-/// function.
+/// function template specialization or member function of a class template
+/// specialization.
+///
+/// \param Recursive if true, recursively instantiates any functions that
+/// are required by this instantiation.
void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
- FunctionDecl *Function) {
+ FunctionDecl *Function,
+ bool Recursive) {
if (Function->isInvalidDecl())
return;
- assert(!Function->getBody(Context) && "Already instantiated!");
+ assert(!Function->getBody() && "Already instantiated!");
// Find the function body that we'll be substituting.
const FunctionDecl *PatternDecl = 0;
@@ -658,7 +711,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
PatternDecl = Function->getInstantiatedFromMemberFunction();
Stmt *Pattern = 0;
if (PatternDecl)
- Pattern = PatternDecl->getBody(Context, PatternDecl);
+ Pattern = PatternDecl->getBody(PatternDecl);
if (!Pattern)
return;
@@ -667,6 +720,13 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
if (Inst)
return;
+ // If we're performing recursive template instantiation, create our own
+ // queue of pending implicit instantiations that we will instantiate later,
+ // while we're still within our own instantiation context.
+ std::deque<PendingImplicitInstantiation> SavedPendingImplicitInstantiations;
+ if (Recursive)
+ PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations);
+
ActOnStartOfFunctionDef(0, DeclPtrTy::make(Function));
// Introduce a new scope where local variable instantiations will be
@@ -695,6 +755,15 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
DeclGroupRef DG(Function);
Consumer.HandleTopLevelDecl(DG);
+
+ if (Recursive) {
+ // Instantiate any pending implicit instantiations found during the
+ // instantiation of this template.
+ PerformPendingImplicitInstantiations();
+
+ // Restore the set of pending implicit instantiations.
+ PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations);
+ }
}
/// \brief Instantiate the definition of the given variable from its
@@ -787,8 +856,7 @@ NamedDecl * Sema::InstantiateCurrentDeclRef(NamedDecl *D) {
// find the instantiation of the declaration D.
NamedDecl *Result = 0;
if (D->getDeclName()) {
- DeclContext::lookup_result Found
- = ParentDC->lookup(Context, D->getDeclName());
+ DeclContext::lookup_result Found = ParentDC->lookup(D->getDeclName());
Result = findInstantiationOf(Context, D, Found.first, Found.second);
} else {
// Since we don't have a name for the entity we're looking for,
@@ -800,8 +868,8 @@ NamedDecl * Sema::InstantiateCurrentDeclRef(NamedDecl *D) {
//
// FIXME: Find a better way to find these instantiations!
Result = findInstantiationOf(Context, D,
- ParentDC->decls_begin(Context),
- ParentDC->decls_end(Context));
+ ParentDC->decls_begin(),
+ ParentDC->decls_end());
}
assert(Result && "Unable to find instantiation of declaration!");
D = Result;
@@ -838,12 +906,12 @@ NamedDecl * Sema::InstantiateCurrentDeclRef(NamedDecl *D) {
void Sema::PerformPendingImplicitInstantiations() {
while (!PendingImplicitInstantiations.empty()) {
PendingImplicitInstantiation Inst = PendingImplicitInstantiations.front();
- PendingImplicitInstantiations.pop();
+ PendingImplicitInstantiations.pop_front();
if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Inst.first))
- if (!Function->getBody(Context))
- InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function);
+ if (!Function->getBody())
+ InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function, true);
- // FIXME: instantiation static member variables
+ // FIXME: instantiate static member variables
}
}
diff --git a/lib/Sema/SemaTemplateInstantiateExpr.cpp b/lib/Sema/SemaTemplateInstantiateExpr.cpp
index 65a35f92f7c6..c82e1a7da3c9 100644
--- a/lib/Sema/SemaTemplateInstantiateExpr.cpp
+++ b/lib/Sema/SemaTemplateInstantiateExpr.cpp
@@ -107,12 +107,49 @@ TemplateExprInstantiator::VisitUnresolvedFunctionNameExpr(
}
Sema::OwningExprResult
+TemplateExprInstantiator::VisitTemplateIdRefExpr(TemplateIdRefExpr *E) {
+ TemplateName Template
+ = SemaRef.InstantiateTemplateName(E->getTemplateName(), E->getTemplateNameLoc(),
+ TemplateArgs);
+ // FIXME: Can InstantiateTemplateName report an error?
+
+ llvm::SmallVector<TemplateArgument, 4> InstantiatedArgs;
+ for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
+ TemplateArgument InstArg = SemaRef.Instantiate(E->getTemplateArgs()[I],
+ TemplateArgs);
+ if (InstArg.isNull())
+ return SemaRef.ExprError();
+
+ InstantiatedArgs.push_back(InstArg);
+ }
+
+ // FIXME: It's possible that we'll find out now that the template name
+ // actually refers to a type, in which case this is a functional cast.
+ // Implement this!
+
+ return SemaRef.BuildTemplateIdExpr(Template, E->getTemplateNameLoc(),
+ E->getLAngleLoc(),
+ InstantiatedArgs.data(),
+ InstantiatedArgs.size(),
+ E->getRAngleLoc());
+}
+
+Sema::OwningExprResult
TemplateExprInstantiator::VisitDeclRefExpr(DeclRefExpr *E) {
NamedDecl *D = E->getDecl();
if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
assert(NTTP->getDepth() == 0 && "No nested templates yet");
- const TemplateArgument &Arg = TemplateArgs[NTTP->getPosition()];
+ // If the corresponding template argument is NULL or non-existent, it's
+ // because we are performing instantiation from explicitly-specified
+ // template arguments in a function template, but there were some
+ // arguments left unspecified.
+ if (NTTP->getPosition() >= TemplateArgs.size() ||
+ TemplateArgs[NTTP->getPosition()].isNull())
+ return SemaRef.Owned(E); // FIXME: Clone the expression!
+
+ const TemplateArgument &Arg = TemplateArgs[NTTP->getPosition()];
+
// The template argument itself might be an expression, in which
// case we just return that expression.
if (Arg.getKind() == TemplateArgument::Expression)
@@ -156,18 +193,15 @@ TemplateExprInstantiator::VisitDeclRefExpr(DeclRefExpr *E) {
false, false));
}
- ValueDecl *NewD
- = dyn_cast_or_null<ValueDecl>(SemaRef.InstantiateCurrentDeclRef(D));
- if (!NewD)
+ NamedDecl *InstD = SemaRef.InstantiateCurrentDeclRef(D);
+ if (!InstD)
return SemaRef.ExprError();
- // FIXME: Build QualifiedDeclRefExpr?
- QualType T = NewD->getType();
- return SemaRef.Owned(new (SemaRef.Context) DeclRefExpr(NewD,
- T.getNonReferenceType(),
- E->getLocation(),
- T->isDependentType(),
- T->isDependentType()));
+ // FIXME: nested-name-specifier for QualifiedDeclRefExpr
+ return SemaRef.BuildDeclarationNameExpr(E->getLocation(), InstD,
+ /*FIXME:*/false,
+ /*FIXME:*/0,
+ /*FIXME:*/false);
}
Sema::OwningExprResult
@@ -525,8 +559,7 @@ TemplateExprInstantiator::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
const IdentifierInfo &Name
= SemaRef.Context.Idents.get("__builtin_shufflevector");
TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
- DeclContext::lookup_result Lookup
- = TUDecl->lookup(SemaRef.Context, DeclarationName(&Name));
+ DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
assert(Lookup.first != Lookup.second && "No __builtin_shufflevector?");
// Build a reference to the __builtin_shufflevector builtin
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index c6bcdc36f132..3756df870c2c 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -17,6 +17,7 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/Parse/DeclSpec.h"
+#include "llvm/ADT/SmallPtrSet.h"
using namespace clang;
/// \brief Perform adjustment on the parameter type of a function.
@@ -89,8 +90,8 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS,
case DeclSpec::TST_unspecified:
// "<proto1,proto2>" is an objc qualified ID with a missing id.
if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) {
- Result = Context.getObjCQualifiedIdType((ObjCProtocolDecl**)PQ,
- DS.getNumProtocolQualifiers());
+ Result = Context.getObjCObjectPointerType(0, (ObjCProtocolDecl**)PQ,
+ DS.getNumProtocolQualifiers());
break;
}
@@ -200,8 +201,8 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS,
DS.getNumProtocolQualifiers());
else if (Result == Context.getObjCIdType())
// id<protocol-list>
- Result = Context.getObjCQualifiedIdType((ObjCProtocolDecl**)PQ,
- DS.getNumProtocolQualifiers());
+ Result = Context.getObjCObjectPointerType(0, (ObjCProtocolDecl**)PQ,
+ DS.getNumProtocolQualifiers());
else if (Result == Context.getObjCClassType()) {
if (DeclLoc.isInvalid())
DeclLoc = DS.getSourceRange().getBegin();
@@ -242,7 +243,11 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS,
Expr *E = static_cast<Expr *>(DS.getTypeRep());
assert(E && "Didn't get an expression for decltype?");
// TypeQuals handled by caller.
- Result = Context.getDecltypeType(E);
+ Result = BuildDecltypeType(E);
+ if (Result.isNull()) {
+ Result = Context.IntTy;
+ isInvalid = true;
+ }
break;
}
case DeclSpec::TST_auto: {
@@ -693,7 +698,7 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class,
// C++ 8.3.3p3: A pointer to member shall not pointer to ... a member
// with reference type, or "cv void."
if (T->isReferenceType()) {
- Diag(Loc, diag::err_illegal_decl_pointer_to_reference)
+ Diag(Loc, diag::err_illegal_decl_mempointer_to_reference)
<< (Entity? Entity.getAsString() : "type name");
return QualType();
}
@@ -814,9 +819,6 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip,
case Declarator::KNRTypeListContext:
assert(0 && "K&R type lists aren't allowed in C++");
break;
- default:
- printf("context: %d\n", D.getContext());
- assert(0);
case Declarator::PrototypeContext:
Error = 0; // Function prototype
break;
@@ -1062,6 +1064,13 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip,
break;
}
case DeclaratorChunk::MemberPointer:
+ // Verify that we're not building a pointer to pointer to function with
+ // exception specification.
+ if (getLangOptions().CPlusPlus && CheckDistantExceptionSpec(T)) {
+ Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec);
+ D.setInvalidType(true);
+ // Build the type anyway.
+ }
// The scope spec must refer to a class, or be dependent.
QualType ClsType;
if (isDependentScopeSpecifier(DeclType.Mem.Scope())) {
@@ -1186,6 +1195,45 @@ bool Sema::CheckDistantExceptionSpec(QualType T) {
return FnT->hasExceptionSpec();
}
+/// CheckEquivalentExceptionSpec - Check if the two types have equivalent
+/// exception specifications. Exception specifications are equivalent if
+/// they allow exactly the same set of exception types. It does not matter how
+/// that is achieved. See C++ [except.spec]p2.
+bool Sema::CheckEquivalentExceptionSpec(
+ const FunctionProtoType *Old, SourceLocation OldLoc,
+ const FunctionProtoType *New, SourceLocation NewLoc) {
+ bool OldAny = !Old->hasExceptionSpec() || Old->hasAnyExceptionSpec();
+ bool NewAny = !New->hasExceptionSpec() || New->hasAnyExceptionSpec();
+ if (OldAny && NewAny)
+ return false;
+ if (OldAny || NewAny) {
+ Diag(NewLoc, diag::err_mismatched_exception_spec);
+ Diag(OldLoc, diag::note_previous_declaration);
+ return true;
+ }
+
+ bool Success = true;
+ // Both have a definite exception spec. Collect the first set, then compare
+ // to the second.
+ llvm::SmallPtrSet<const Type*, 8> Types;
+ for (FunctionProtoType::exception_iterator I = Old->exception_begin(),
+ E = Old->exception_end(); I != E; ++I)
+ Types.insert(Context.getCanonicalType(*I).getTypePtr());
+
+ for (FunctionProtoType::exception_iterator I = New->exception_begin(),
+ E = New->exception_end(); I != E && Success; ++I)
+ Success = Types.erase(Context.getCanonicalType(*I).getTypePtr());
+
+ Success = Success && Types.empty();
+
+ if (Success) {
+ return false;
+ }
+ Diag(NewLoc, diag::err_mismatched_exception_spec);
+ Diag(OldLoc, diag::note_previous_declaration);
+ return true;
+}
+
/// ObjCGetTypeForMethodDefinition - Builds the type for a method definition
/// declarator
QualType Sema::ObjCGetTypeForMethodDefinition(DeclPtrTy D) {
@@ -1466,3 +1514,16 @@ QualType Sema::getQualifiedNameType(const CXXScopeSpec &SS, QualType T) {
= static_cast<NestedNameSpecifier *>(SS.getScopeRep());
return Context.getQualifiedNameType(NNS, T);
}
+
+QualType Sema::BuildTypeofExprType(Expr *E) {
+ return Context.getTypeOfExprType(E);
+}
+
+QualType Sema::BuildDecltypeType(Expr *E) {
+ if (E->getType() == Context.OverloadTy) {
+ Diag(E->getLocStart(),
+ diag::err_cannot_determine_declared_type_of_overloaded_function);
+ return QualType();
+ }
+ return Context.getDecltypeType(E);
+}