aboutsummaryrefslogtreecommitdiff
path: root/lib/AST
diff options
context:
space:
mode:
authorEd Schouten <ed@FreeBSD.org>2009-07-04 13:58:54 +0000
committerEd Schouten <ed@FreeBSD.org>2009-07-04 13:58:54 +0000
commit5362a71c02e7d448a8ce98cf00c47e353fba5d04 (patch)
tree8ddfe382e1c6d590dc240e76f7cd45cea5c78e24 /lib/AST
parent4ebdf5c4f587daef4e0be499802eac3a7a49bf2f (diff)
Notes
Diffstat (limited to 'lib/AST')
-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
16 files changed, 721 insertions, 284 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";
}