summaryrefslogtreecommitdiffstats
path: root/lib/AST
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST')
-rw-r--r--lib/AST/ASTContext.cpp101
-rw-r--r--lib/AST/Decl.cpp35
-rw-r--r--lib/AST/DeclBase.cpp48
-rw-r--r--lib/AST/DeclCXX.cpp73
-rw-r--r--lib/AST/DeclTemplate.cpp41
-rw-r--r--lib/AST/Expr.cpp37
-rw-r--r--lib/AST/ExprCXX.cpp9
-rw-r--r--lib/AST/StmtPrinter.cpp8
-rw-r--r--lib/AST/Type.cpp107
9 files changed, 291 insertions, 168 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 7ed9e45..b80142f 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -222,7 +222,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>())
+ if (const AlignedAttr* AA = D->getAttr<AlignedAttr>(*this))
Align = std::max(Align, AA->getAlignment());
if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
@@ -369,7 +369,7 @@ ASTContext::getTypeInfo(const Type *T) {
// FIXME: Pointers into different addr spaces could have different sizes and
// alignment requirements: getPointerInfo should take an AddrSpace.
return getTypeInfo(QualType(cast<ExtQualType>(T)->getBaseType(), 0));
- case Type::ObjCQualifiedId:
+ case Type::ObjCObjectPointer:
case Type::ObjCQualifiedInterface:
Width = Target.getPointerWidth(0);
Align = Target.getPointerAlign(0);
@@ -445,7 +445,7 @@ ASTContext::getTypeInfo(const Type *T) {
case Type::Typedef: {
const TypedefDecl *Typedef = cast<TypedefType>(T)->getDecl();
- if (const AlignedAttr *Aligned = Typedef->getAttr<AlignedAttr>()) {
+ if (const AlignedAttr *Aligned = Typedef->getAttr<AlignedAttr>(*this)) {
Align = Aligned->getAlignment();
Width = getTypeSize(Typedef->getUnderlyingType().getTypePtr());
} else
@@ -505,7 +505,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>())
+ if (const PackedAttr *PA = FD->getAttr<PackedAttr>(Context))
FieldPacking = PA->getAlignment();
if (const Expr *BitWidthExpr = FD->getBitWidth()) {
@@ -525,7 +525,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>())
+ if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>(Context))
FieldAlign = std::max(FieldAlign, AA->getAlignment());
// Check if we need to add padding to give the field the correct
@@ -565,7 +565,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>())
+ if (const AlignedAttr *AA = FD->getAttr<AlignedAttr>(Context))
FieldAlign = std::max(FieldAlign, AA->getAlignment());
// Round up the current record size to the field's alignment boundary.
@@ -731,10 +731,10 @@ ASTContext::getObjCLayout(const ObjCInterfaceDecl *D,
}
unsigned StructPacking = 0;
- if (const PackedAttr *PA = D->getAttr<PackedAttr>())
+ if (const PackedAttr *PA = D->getAttr<PackedAttr>(*this))
StructPacking = PA->getAlignment();
- if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
+ if (const AlignedAttr *AA = D->getAttr<AlignedAttr>(*this))
NewEntry->SetAlignment(std::max(NewEntry->getAlignment(),
AA->getAlignment()));
@@ -783,10 +783,10 @@ const ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D) {
bool IsUnion = D->isUnion();
unsigned StructPacking = 0;
- if (const PackedAttr *PA = D->getAttr<PackedAttr>())
+ if (const PackedAttr *PA = D->getAttr<PackedAttr>(*this))
StructPacking = PA->getAlignment();
- if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
+ if (const AlignedAttr *AA = D->getAttr<AlignedAttr>(*this))
NewEntry->SetAlignment(std::max(NewEntry->getAlignment(),
AA->getAlignment()));
@@ -1269,6 +1269,18 @@ QualType ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) {
return QualType(New, 0);
}
+QualType ASTContext::getDependentSizedExtVectorType(QualType vecType,
+ Expr *SizeExpr,
+ SourceLocation AttrLoc) {
+ DependentSizedExtVectorType *New =
+ new (*this,8) DependentSizedExtVectorType(vecType, QualType(),
+ SizeExpr, AttrLoc);
+
+ DependentSizedExtVectorTypes.push_back(New);
+ Types.push_back(New);
+ return QualType(New, 0);
+}
+
/// getFunctionNoProtoType - Return a K&R style C function type like 'int()'.
///
QualType ASTContext::getFunctionNoProtoType(QualType ResultTy) {
@@ -1414,11 +1426,13 @@ QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl) {
}
/// \brief Retrieve the template type parameter type for a template
-/// parameter with the given depth, index, and (optionally) name.
+/// parameter or parameter pack with the given depth, index, and (optionally)
+/// name.
QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index,
+ bool ParameterPack,
IdentifierInfo *Name) {
llvm::FoldingSetNodeID ID;
- TemplateTypeParmType::Profile(ID, Depth, Index, Name);
+ TemplateTypeParmType::Profile(ID, Depth, Index, ParameterPack, Name);
void *InsertPos = 0;
TemplateTypeParmType *TypeParm
= TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
@@ -1426,11 +1440,12 @@ QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index,
if (TypeParm)
return QualType(TypeParm, 0);
- if (Name)
- TypeParm = new (*this, 8) TemplateTypeParmType(Depth, Index, Name,
- getTemplateTypeParmType(Depth, Index));
- else
- TypeParm = new (*this, 8) TemplateTypeParmType(Depth, Index);
+ if (Name) {
+ QualType Canon = getTemplateTypeParmType(Depth, Index, ParameterPack);
+ TypeParm = new (*this, 8) TemplateTypeParmType(Depth, Index, ParameterPack,
+ Name, Canon);
+ } else
+ TypeParm = new (*this, 8) TemplateTypeParmType(Depth, Index, ParameterPack);
Types.push_back(TypeParm);
TemplateTypeParmTypes.InsertNode(TypeParm, InsertPos);
@@ -1563,6 +1578,31 @@ static void SortAndUniqueProtocols(ObjCProtocolDecl **&Protocols,
NumProtocols = ProtocolsEnd-Protocols;
}
+/// getObjCObjectPointerType - Return a ObjCObjectPointerType type for
+/// the given interface decl and the conforming protocol list.
+QualType ASTContext::getObjCObjectPointerType(ObjCInterfaceDecl *Decl,
+ ObjCProtocolDecl **Protocols,
+ unsigned NumProtocols) {
+ // Sort the protocol list alphabetically to canonicalize it.
+ if (NumProtocols)
+ SortAndUniqueProtocols(Protocols, NumProtocols);
+
+ llvm::FoldingSetNodeID ID;
+ ObjCObjectPointerType::Profile(ID, Decl, Protocols, NumProtocols);
+
+ void *InsertPos = 0;
+ if (ObjCObjectPointerType *QT =
+ ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
+ return QualType(QT, 0);
+
+ // No Match;
+ ObjCObjectPointerType *QType =
+ new (*this,8) ObjCObjectPointerType(Decl, Protocols, NumProtocols);
+
+ Types.push_back(QType);
+ ObjCObjectPointerTypes.InsertNode(QType, InsertPos);
+ return QualType(QType, 0);
+}
/// getObjCQualifiedInterfaceType - Return a ObjCQualifiedInterfaceType type for
/// the given interface decl and the conforming protocol list.
@@ -1592,23 +1632,7 @@ QualType ASTContext::getObjCQualifiedInterfaceType(ObjCInterfaceDecl *Decl,
/// and the conforming protocol list.
QualType ASTContext::getObjCQualifiedIdType(ObjCProtocolDecl **Protocols,
unsigned NumProtocols) {
- // Sort the protocol list alphabetically to canonicalize it.
- SortAndUniqueProtocols(Protocols, NumProtocols);
-
- llvm::FoldingSetNodeID ID;
- ObjCQualifiedIdType::Profile(ID, Protocols, NumProtocols);
-
- void *InsertPos = 0;
- if (ObjCQualifiedIdType *QT =
- ObjCQualifiedIdTypes.FindNodeOrInsertPos(ID, InsertPos))
- return QualType(QT, 0);
-
- // No Match;
- ObjCQualifiedIdType *QType =
- new (*this,8) ObjCQualifiedIdType(Protocols, NumProtocols);
- Types.push_back(QType);
- ObjCQualifiedIdTypes.InsertNode(QType, InsertPos);
- return QualType(QType, 0);
+ return getObjCObjectPointerType(0, Protocols, NumProtocols);
}
/// getTypeOfExprType - Unlike many "get<Type>" functions, we can't unique
@@ -2398,9 +2422,9 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
if (FD || EncodingProperty) {
// Note that we do extended encoding of protocol qualifer list
// Only when doing ivar or property encoding.
- const ObjCQualifiedIdType *QIDT = T->getAsObjCQualifiedIdType();
+ const ObjCObjectPointerType *QIDT = T->getAsObjCQualifiedIdType();
S += '"';
- for (ObjCQualifiedIdType::qual_iterator I = QIDT->qual_begin(),
+ for (ObjCObjectPointerType::qual_iterator I = QIDT->qual_begin(),
E = QIDT->qual_end(); I != E; ++I) {
S += '<';
S += (*I)->getNameAsString();
@@ -2758,7 +2782,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>())
+ if (TD->getAttr<ObjCNSObjectAttr>(*const_cast<ASTContext*>(this)))
return true;
}
return false;
@@ -3283,7 +3307,8 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {
return QualType();
}
- case Type::ObjCQualifiedId:
+ case Type::ObjCObjectPointer:
+ // FIXME: finish
// Distinct qualified id's are not compatible.
return QualType();
case Type::FixedWidthInt:
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index a3e406b..bf63932 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -315,6 +315,12 @@ void VarDecl::Destroy(ASTContext& C) {
VarDecl::~VarDecl() {
}
+SourceRange VarDecl::getSourceRange() const {
+ if (getInit())
+ return SourceRange(getLocation(), getInit()->getLocEnd());
+ return SourceRange(getLocation(), getLocation());
+}
+
bool VarDecl::isTentativeDefinition(ASTContext &Context) const {
if (!isFileVarDecl() || Context.getLangOptions().CPlusPlus)
return false;
@@ -371,6 +377,12 @@ Stmt *FunctionDecl::getBodyIfAvailable() const {
return 0;
}
+void FunctionDecl::setBody(Stmt *B) {
+ Body = B;
+ if (B && EndRangeLoc < B->getLocEnd())
+ EndRangeLoc = B->getLocEnd();
+}
+
bool FunctionDecl::isMain() const {
return getDeclContext()->getLookupContext()->isTranslationUnit() &&
getIdentifier() && getIdentifier()->isStr("main");
@@ -380,13 +392,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>();
+ return getStorageClass() != Static && !getAttr<OverloadableAttr>(Context);
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>();
+ return getStorageClass() != Static &&
+ !getAttr<OverloadableAttr>(Context);
break;
}
@@ -451,7 +464,7 @@ unsigned FunctionDecl::getBuiltinID(ASTContext &Context) const {
if (isa<LinkageSpecDecl>(getDeclContext()) &&
cast<LinkageSpecDecl>(getDeclContext())->getLanguage()
== LinkageSpecDecl::lang_c &&
- !getAttr<OverloadableAttr>())
+ !getAttr<OverloadableAttr>(Context))
return BuiltinID;
// Not a builtin
@@ -480,6 +493,10 @@ void FunctionDecl::setParams(ASTContext& C, ParmVarDecl **NewParamInfo,
void *Mem = C.Allocate(sizeof(ParmVarDecl*)*NumParams);
ParamInfo = new (Mem) ParmVarDecl*[NumParams];
memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
+
+ // Update source range.
+ if (EndRangeLoc < NewParamInfo[NumParams-1]->getLocEnd())
+ EndRangeLoc = NewParamInfo[NumParams-1]->getLocEnd();
}
}
@@ -496,25 +513,25 @@ unsigned FunctionDecl::getMinRequiredArguments() const {
return NumRequiredArgs;
}
-bool FunctionDecl::hasActiveGNUInlineAttribute() const {
- if (!isInline() || !hasAttr<GNUInlineAttr>())
+bool FunctionDecl::hasActiveGNUInlineAttribute(ASTContext &Context) const {
+ if (!isInline() || !hasAttr<GNUInlineAttr>(Context))
return false;
for (const FunctionDecl *FD = getPreviousDeclaration(); FD;
FD = FD->getPreviousDeclaration()) {
- if (FD->isInline() && !FD->hasAttr<GNUInlineAttr>())
+ if (FD->isInline() && !FD->hasAttr<GNUInlineAttr>(Context))
return false;
}
return true;
}
-bool FunctionDecl::isExternGNUInline() const {
- if (!hasActiveGNUInlineAttribute())
+bool FunctionDecl::isExternGNUInline(ASTContext &Context) const {
+ if (!hasActiveGNUInlineAttribute(Context))
return false;
for (const FunctionDecl *FD = this; FD; FD = FD->getPreviousDeclaration())
- if (FD->getStorageClass() == Extern && FD->hasAttr<GNUInlineAttr>())
+ if (FD->getStorageClass() == Extern && FD->hasAttr<GNUInlineAttr>(Context))
return true;
return false;
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index a39a506..02e71d7 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -38,12 +38,6 @@ using namespace clang;
static bool StatSwitch = false;
-// This keeps track of all decl attributes. Since so few decls have attrs, we
-// keep them in a hash map instead of wasting space in the Decl class.
-typedef llvm::DenseMap<const Decl*, Attr*> DeclAttrMapTy;
-
-static DeclAttrMapTy *DeclAttrs = 0;
-
const char *Decl::getDeclKindName() const {
switch (DeclKind) {
default: assert(0 && "Declaration not in DeclNodes.def!");
@@ -170,6 +164,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case ParmVar:
case OriginalParmVar:
case NonTypeTemplateParm:
+ case Using:
case ObjCMethod:
case ObjCContainer:
case ObjCCategory:
@@ -224,11 +219,8 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
}
}
-void Decl::addAttr(Attr *NewAttr) {
- if (!DeclAttrs)
- DeclAttrs = new DeclAttrMapTy();
-
- Attr *&ExistingAttr = (*DeclAttrs)[this];
+void Decl::addAttr(ASTContext &Context, Attr *NewAttr) {
+ Attr *&ExistingAttr = Context.getDeclAttrs(this);
NewAttr->setNext(ExistingAttr);
ExistingAttr = NewAttr;
@@ -236,25 +228,19 @@ void Decl::addAttr(Attr *NewAttr) {
HasAttrs = true;
}
-void Decl::invalidateAttrs() {
+void Decl::invalidateAttrs(ASTContext &Context) {
if (!HasAttrs) return;
-
+
HasAttrs = false;
- (*DeclAttrs)[this] = 0;
- DeclAttrs->erase(this);
-
- if (DeclAttrs->empty()) {
- delete DeclAttrs;
- DeclAttrs = 0;
- }
+ Context.eraseDeclAttrs(this);
}
-const Attr *Decl::getAttrsImpl() const {
+const Attr *Decl::getAttrsImpl(ASTContext &Context) const {
assert(HasAttrs && "getAttrs() should verify this!");
- return (*DeclAttrs)[this];
+ return Context.getDeclAttrs(this);
}
-void Decl::swapAttrs(Decl *RHS) {
+void Decl::swapAttrs(ASTContext &Context, Decl *RHS) {
bool HasLHSAttr = this->HasAttrs;
bool HasRHSAttr = RHS->HasAttrs;
@@ -263,17 +249,17 @@ void Decl::swapAttrs(Decl *RHS) {
// If 'this' has no attrs, swap the other way.
if (!HasLHSAttr)
- return RHS->swapAttrs(this);
+ return RHS->swapAttrs(Context, this);
// Handle the case when both decls have attrs.
if (HasRHSAttr) {
- std::swap((*DeclAttrs)[this], (*DeclAttrs)[RHS]);
+ std::swap(Context.getDeclAttrs(this), Context.getDeclAttrs(RHS));
return;
}
// Otherwise, LHS has an attr and RHS doesn't.
- (*DeclAttrs)[RHS] = (*DeclAttrs)[this];
- (*DeclAttrs).erase(this);
+ Context.getDeclAttrs(RHS) = Context.getDeclAttrs(this);
+ Context.eraseDeclAttrs(this);
this->HasAttrs = false;
RHS->HasAttrs = true;
}
@@ -282,12 +268,8 @@ void Decl::swapAttrs(Decl *RHS) {
void Decl::Destroy(ASTContext &C) {
// Free attributes for this decl.
if (HasAttrs) {
- DeclAttrMapTy::iterator it = DeclAttrs->find(this);
- assert(it != DeclAttrs->end() && "No attrs found but HasAttrs is true!");
-
- // release attributes.
- it->second->Destroy(C);
- invalidateAttrs();
+ C.getDeclAttrs(this)->Destroy(C);
+ invalidateAttrs(C);
HasAttrs = false;
}
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 8430da2..7a930d7 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -128,36 +128,33 @@ bool CXXRecordDecl::hasConstCopyAssignment(ASTContext &Context) const {
void
CXXRecordDecl::addedConstructor(ASTContext &Context,
CXXConstructorDecl *ConDecl) {
- if (!ConDecl->isImplicit()) {
- // Note that we have a user-declared constructor.
- UserDeclaredConstructor = true;
-
- // C++ [dcl.init.aggr]p1:
- // An aggregate is an array or a class (clause 9) with no
- // user-declared constructors (12.1) [...].
- Aggregate = false;
-
- // C++ [class]p4:
- // A POD-struct is an aggregate class [...]
- PlainOldData = false;
-
- // C++ [class.ctor]p5:
- // A constructor is trivial if it is an implicitly-declared default
- // constructor.
- HasTrivialConstructor = false;
+ assert(!ConDecl->isImplicit() && "addedConstructor - not for implicit decl");
+ // Note that we have a user-declared constructor.
+ UserDeclaredConstructor = true;
+
+ // C++ [dcl.init.aggr]p1:
+ // An aggregate is an array or a class (clause 9) with no
+ // user-declared constructors (12.1) [...].
+ Aggregate = false;
+
+ // C++ [class]p4:
+ // A POD-struct is an aggregate class [...]
+ PlainOldData = false;
+
+ // C++ [class.ctor]p5:
+ // A constructor is trivial if it is an implicitly-declared default
+ // constructor.
+ HasTrivialConstructor = false;
- // Note when we have a user-declared copy constructor, which will
- // suppress the implicit declaration of a copy constructor.
- if (ConDecl->isCopyConstructor(Context))
- UserDeclaredCopyConstructor = true;
- }
+ // Note when we have a user-declared copy constructor, which will
+ // suppress the implicit declaration of a copy constructor.
+ if (ConDecl->isCopyConstructor(Context))
+ UserDeclaredCopyConstructor = true;
}
void CXXRecordDecl::addedAssignmentOperator(ASTContext &Context,
CXXMethodDecl *OpDecl) {
// We're interested specifically in copy assignment operators.
- // Unlike addedConstructor, this method is not called for implicit
- // declarations.
const FunctionProtoType *FnType = OpDecl->getType()->getAsFunctionProtoType();
assert(FnType && "Overloaded operator has no proto function type.");
assert(FnType->getNumArgs() == 1 && !FnType->isVariadic());
@@ -187,10 +184,28 @@ void CXXRecordDecl::addConversionFunction(ASTContext &Context,
Conversions.addOverload(ConvDecl);
}
+
+CXXConstructorDecl *
+CXXRecordDecl::getDefaultConstructor(ASTContext &Context) {
+ QualType ClassType = Context.getTypeDeclType(this);
+ DeclarationName ConstructorName
+ = Context.DeclarationNames.getCXXConstructorName(
+ Context.getCanonicalType(ClassType.getUnqualifiedType()));
+
+ DeclContext::lookup_const_iterator Con, ConEnd;
+ for (llvm::tie(Con, ConEnd) = lookup(Context, ConstructorName);
+ Con != ConEnd; ++Con) {
+ CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
+ if (Constructor->isDefaultConstructor())
+ return Constructor;
+ }
+ return 0;
+}
+
const CXXDestructorDecl *
CXXRecordDecl::getDestructor(ASTContext &Context) {
QualType ClassType = Context.getTypeDeclType(this);
-
+
DeclarationName Name
= Context.DeclarationNames.getCXXDestructorName(ClassType);
@@ -428,6 +443,14 @@ NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC,
Qualifier, IdentLoc, Namespace);
}
+UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, SourceRange NNR, SourceLocation TargetNL,
+ SourceLocation UL, NamedDecl* Target,
+ NestedNameSpecifier* TargetNNS, bool IsTypeNameArg) {
+ return new (C) UsingDecl(DC, L, NNR, TargetNL, UL, Target,
+ TargetNNS, IsTypeNameArg);
+}
+
StaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L, Expr *AssertExpr,
StringLiteral *Message) {
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 5b1bf9b..23c2637 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -190,7 +190,7 @@ TemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L, unsigned D, unsigned P,
IdentifierInfo *Id, bool Typename,
bool ParameterPack) {
- QualType Type = C.getTemplateTypeParmType(D, P, Id);
+ QualType Type = C.getTemplateTypeParmType(D, P, ParameterPack, Id);
return new (C) TemplateTypeParmDecl(DC, L, Id, Typename, Type, ParameterPack);
}
@@ -238,6 +238,22 @@ TemplateArgument::TemplateArgument(Expr *E) : Kind(Expression) {
StartLoc = E->getSourceRange().getBegin();
}
+/// \brief Construct a template argument pack.
+TemplateArgument::TemplateArgument(SourceLocation Loc, TemplateArgument *args,
+ unsigned NumArgs, bool CopyArgs)
+ : Kind(Pack) {
+ Args.NumArgs = NumArgs;
+ Args.CopyArgs = CopyArgs;
+ if (!Args.CopyArgs) {
+ Args.Args = args;
+ return;
+ }
+
+ Args.Args = new TemplateArgument[NumArgs];
+ for (unsigned I = 0; I != NumArgs; ++I)
+ Args.Args[I] = args[I];
+}
+
//===----------------------------------------------------------------------===//
// TemplateArgumentListBuilder Implementation
//===----------------------------------------------------------------------===//
@@ -249,25 +265,28 @@ void TemplateArgumentListBuilder::push_back(const TemplateArgument& Arg) {
break;
}
- if (!isAddingFromParameterPack()) {
- // Add begin and end indicies.
- Indices.push_back(Args.size());
- Indices.push_back(Args.size());
- }
-
- Args.push_back(Arg);
+ FlatArgs.push_back(Arg);
+
+ if (!isAddingFromParameterPack())
+ StructuredArgs.push_back(Arg);
}
void TemplateArgumentListBuilder::BeginParameterPack() {
assert(!isAddingFromParameterPack() && "Already adding to parameter pack!");
-
- Indices.push_back(Args.size());
+
+ PackBeginIndex = FlatArgs.size();
}
void TemplateArgumentListBuilder::EndParameterPack() {
assert(isAddingFromParameterPack() && "Not adding to parameter pack!");
+
+ unsigned NumArgs = FlatArgs.size() - PackBeginIndex;
+ TemplateArgument *Args = NumArgs ? &FlatArgs[PackBeginIndex] : 0;
+
+ StructuredArgs.push_back(TemplateArgument(SourceLocation(), Args, NumArgs,
+ /*CopyArgs=*/false));
- Indices.push_back(Args.size());
+ PackBeginIndex = std::numeric_limits<unsigned>::max();
}
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 309be41..4a3ad26 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -456,7 +456,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) const {
+ SourceRange &R2, ASTContext &Context) const {
// Don't warn if the expr is type dependent. The type could end up
// instantiating to void.
if (isTypeDependent())
@@ -469,7 +469,7 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
return true;
case ParenExprClass:
return cast<ParenExpr>(this)->getSubExpr()->
- isUnusedResultAWarning(Loc, R1, R2);
+ isUnusedResultAWarning(Loc, R1, R2, Context);
case UnaryOperatorClass: {
const UnaryOperator *UO = cast<UnaryOperator>(this);
@@ -492,7 +492,7 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
return false;
break;
case UnaryOperator::Extension:
- return UO->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2);
+ return UO->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Context);
}
Loc = UO->getOperatorLoc();
R1 = UO->getSubExpr()->getSourceRange();
@@ -502,8 +502,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) ||
- BO->getLHS()->isUnusedResultAWarning(Loc, R1, R2);
+ return BO->getRHS()->isUnusedResultAWarning(Loc, R1, R2, Context) ||
+ BO->getLHS()->isUnusedResultAWarning(Loc, R1, R2, Context);
if (BO->isAssignmentOp())
return false;
@@ -519,9 +519,10 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
// The condition must be evaluated, but if either the LHS or RHS is a
// warning, warn about them.
const ConditionalOperator *Exp = cast<ConditionalOperator>(this);
- if (Exp->getLHS() && Exp->getLHS()->isUnusedResultAWarning(Loc, R1, R2))
+ if (Exp->getLHS() &&
+ Exp->getLHS()->isUnusedResultAWarning(Loc, R1, R2, Context))
return true;
- return Exp->getRHS()->isUnusedResultAWarning(Loc, R1, R2);
+ return Exp->getRHS()->isUnusedResultAWarning(Loc, R1, R2, Context);
}
case MemberExprClass:
@@ -554,8 +555,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>() ||
- FD->getAttr<PureAttr>() || FD->getAttr<ConstAttr>()) {
+ if (FD->getAttr<WarnUnusedResultAttr>(Context) ||
+ FD->getAttr<PureAttr>(Context) || FD->getAttr<ConstAttr>(Context)) {
Loc = CE->getCallee()->getLocStart();
R1 = CE->getCallee()->getSourceRange();
@@ -578,7 +579,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);
+ return E->isUnusedResultAWarning(Loc, R1, R2, Context);
Loc = cast<StmtExpr>(this)->getLParenLoc();
R1 = getSourceRange();
@@ -588,8 +589,8 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
// If this is a cast to void, check the operand. Otherwise, the result of
// the cast is unused.
if (getType()->isVoidType())
- return cast<CastExpr>(this)->getSubExpr()->isUnusedResultAWarning(Loc,
- R1, R2);
+ return cast<CastExpr>(this)->getSubExpr()
+ ->isUnusedResultAWarning(Loc, R1, R2, Context);
Loc = cast<CStyleCastExpr>(this)->getLParenLoc();
R1 = cast<CStyleCastExpr>(this)->getSubExpr()->getSourceRange();
return true;
@@ -597,8 +598,8 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
// If this is a cast to void, check the operand. Otherwise, the result of
// the cast is unused.
if (getType()->isVoidType())
- return cast<CastExpr>(this)->getSubExpr()->isUnusedResultAWarning(Loc,
- R1, R2);
+ return cast<CastExpr>(this)->getSubExpr()
+ ->isUnusedResultAWarning(Loc, R1, R2, Context);
Loc = cast<CXXFunctionalCastExpr>(this)->getTypeBeginLoc();
R1 = cast<CXXFunctionalCastExpr>(this)->getSubExpr()->getSourceRange();
return true;
@@ -606,11 +607,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);
+ ->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Context);
case CXXDefaultArgExprClass:
return cast<CXXDefaultArgExpr>(this)
- ->getExpr()->isUnusedResultAWarning(Loc, R1, R2);
+ ->getExpr()->isUnusedResultAWarning(Loc, R1, R2, Context);
case CXXNewExprClass:
// FIXME: In theory, there might be new expressions that don't have side
@@ -619,7 +620,7 @@ bool Expr::isUnusedResultAWarning(SourceLocation &Loc, SourceRange &R1,
return false;
case CXXExprWithTemporariesClass:
return cast<CXXExprWithTemporaries>(this)
- ->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2);
+ ->getSubExpr()->isUnusedResultAWarning(Loc, R1, R2, Context);
}
}
@@ -1570,7 +1571,7 @@ ObjCSelectorExpr *ObjCSelectorExpr::Clone(ASTContext &C) const {
}
ObjCProtocolExpr *ObjCProtocolExpr::Clone(ASTContext &C) const {
- return new (C) ObjCProtocolExpr(getType(), Protocol, AtLoc, RParenLoc);
+ return new (C) ObjCProtocolExpr(getType(), TheProtocol, AtLoc, RParenLoc);
}
// constructor for class messages.
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 8fd66a2..18c0f77 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -306,10 +306,11 @@ void CXXConstructExpr::Destroy(ASTContext &C) {
CXXExprWithTemporaries::CXXExprWithTemporaries(Expr *subexpr,
CXXTemporary **temps,
unsigned numtemps,
- bool destroytemps)
+ bool shoulddestroytemps)
: Expr(CXXExprWithTemporariesClass, subexpr->getType(),
subexpr->isTypeDependent(), subexpr->isValueDependent()),
- SubExpr(subexpr), Temps(0), NumTemps(numtemps), DestroyTemps(destroytemps) {
+ SubExpr(subexpr), Temps(0), NumTemps(numtemps),
+ ShouldDestroyTemps(shoulddestroytemps) {
if (NumTemps > 0) {
Temps = new CXXTemporary*[NumTemps];
for (unsigned i = 0; i < NumTemps; ++i)
@@ -321,9 +322,9 @@ CXXExprWithTemporaries *CXXExprWithTemporaries::Create(ASTContext &C,
Expr *SubExpr,
CXXTemporary **Temps,
unsigned NumTemps,
- bool DestroyTemps) {
+ bool ShouldDestroyTemps){
return new (C) CXXExprWithTemporaries(SubExpr, Temps, NumTemps,
- DestroyTemps);
+ ShouldDestroyTemps);
}
void CXXExprWithTemporaries::Destroy(ASTContext &C) {
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 710da63..b300940 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -643,7 +643,8 @@ void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
if (!Node->isPostfix()) {
OS << UnaryOperator::getOpcodeStr(Node->getOpcode());
- // Print a space if this is an "identifier operator" like __real.
+ // Print a space if this is an "identifier operator" like __real, or if
+ // it might be concatenated incorrectly like '+'.
switch (Node->getOpcode()) {
default: break;
case UnaryOperator::Real:
@@ -651,6 +652,11 @@ void StmtPrinter::VisitUnaryOperator(UnaryOperator *Node) {
case UnaryOperator::Extension:
OS << ' ';
break;
+ case UnaryOperator::Plus:
+ case UnaryOperator::Minus:
+ if (isa<UnaryOperator>(Node->getSubExpr()))
+ OS << ' ';
+ break;
}
}
PrintExpr(Node->getSubExpr());
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index e304f54..7b45b21 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -50,6 +50,13 @@ void DependentSizedArrayType::Destroy(ASTContext& C) {
C.Deallocate(this);
}
+void DependentSizedExtVectorType::Destroy(ASTContext& C) {
+ if (SizeExpr)
+ SizeExpr->Destroy(C);
+ this->~DependentSizedExtVectorType();
+ C.Deallocate(this);
+}
+
/// getArrayElementTypeNoTypeQual - If this is an array type, return the
/// element type of the array, potentially with type qualifiers missing.
/// This method should never be used when type qualifiers are meaningful.
@@ -555,6 +562,12 @@ const ObjCInterfaceType *Type::getAsObjCInterfaceType() const {
return dyn_cast<ObjCInterfaceType>(CanonicalType.getUnqualifiedType());
}
+const ObjCObjectPointerType *Type::getAsObjCObjectPointerType() const {
+ // There is no sugar for ObjCObjectPointerType's, just return the
+ // canonical type pointer if it is the right class.
+ return dyn_cast<ObjCObjectPointerType>(CanonicalType.getUnqualifiedType());
+}
+
const ObjCQualifiedInterfaceType *
Type::getAsObjCQualifiedInterfaceType() const {
// There is no sugar for ObjCQualifiedInterfaceType's, just return the
@@ -562,10 +575,14 @@ Type::getAsObjCQualifiedInterfaceType() const {
return dyn_cast<ObjCQualifiedInterfaceType>(CanonicalType.getUnqualifiedType());
}
-const ObjCQualifiedIdType *Type::getAsObjCQualifiedIdType() const {
+const ObjCObjectPointerType *Type::getAsObjCQualifiedIdType() const {
// There is no sugar for ObjCQualifiedIdType's, just return the canonical
// type pointer if it is the right class.
- return dyn_cast<ObjCQualifiedIdType>(CanonicalType.getUnqualifiedType());
+ if (const ObjCObjectPointerType *OPT = getAsObjCObjectPointerType()) {
+ if (OPT->isObjCQualifiedIdType())
+ return OPT;
+ }
+ return 0;
}
const TemplateTypeParmType *Type::getAsTemplateTypeParmType() const {
@@ -770,7 +787,7 @@ bool Type::isScalarType() const {
isa<BlockPointerType>(CanonicalType) ||
isa<MemberPointerType>(CanonicalType) ||
isa<ComplexType>(CanonicalType) ||
- isa<ObjCQualifiedIdType>(CanonicalType);
+ isa<ObjCObjectPointerType>(CanonicalType);
}
/// \brief Determines whether the type is a C++ aggregate type or C
@@ -857,7 +874,7 @@ bool Type::isPODType() const {
case MemberPointer:
case Vector:
case ExtVector:
- case ObjCQualifiedId:
+ case ObjCObjectPointer:
return true;
case Enum:
@@ -912,7 +929,7 @@ bool Type::isSpecifierType() const {
case Typename:
case ObjCInterface:
case ObjCQualifiedInterface:
- case ObjCQualifiedId:
+ case ObjCObjectPointer:
return true;
default:
return false;
@@ -973,28 +990,30 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID) {
getNumExceptions(), exception_begin());
}
-void ObjCQualifiedInterfaceType::Profile(llvm::FoldingSetNodeID &ID,
- const ObjCInterfaceDecl *Decl,
- ObjCProtocolDecl **protocols,
- unsigned NumProtocols) {
+void ObjCObjectPointerType::Profile(llvm::FoldingSetNodeID &ID,
+ const ObjCInterfaceDecl *Decl,
+ ObjCProtocolDecl **protocols,
+ unsigned NumProtocols) {
ID.AddPointer(Decl);
for (unsigned i = 0; i != NumProtocols; i++)
ID.AddPointer(protocols[i]);
}
-void ObjCQualifiedInterfaceType::Profile(llvm::FoldingSetNodeID &ID) {
+void ObjCObjectPointerType::Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getDecl(), &Protocols[0], getNumProtocols());
}
-void ObjCQualifiedIdType::Profile(llvm::FoldingSetNodeID &ID,
- ObjCProtocolDecl **protocols,
- unsigned NumProtocols) {
+void ObjCQualifiedInterfaceType::Profile(llvm::FoldingSetNodeID &ID,
+ const ObjCInterfaceDecl *Decl,
+ ObjCProtocolDecl **protocols,
+ unsigned NumProtocols) {
+ ID.AddPointer(Decl);
for (unsigned i = 0; i != NumProtocols; i++)
ID.AddPointer(protocols[i]);
}
-void ObjCQualifiedIdType::Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, &Protocols[0], getNumProtocols());
+void ObjCQualifiedInterfaceType::Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, getDecl(), &Protocols[0], getNumProtocols());
}
/// LookThroughTypedefs - Return the ultimate type this typedef corresponds to
@@ -1068,6 +1087,10 @@ anyDependentTemplateArguments(const TemplateArgument *Args, unsigned NumArgs) {
Args[Idx].getAsExpr()->isValueDependent())
return true;
break;
+
+ case TemplateArgument::Pack:
+ assert(0 && "FIXME: Implement!");
+ break;
}
}
@@ -1352,6 +1375,19 @@ void DependentSizedArrayType::getAsStringInternal(std::string &S, const Printing
getElementType().getAsStringInternal(S, Policy);
}
+void DependentSizedExtVectorType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
+ getElementType().getAsStringInternal(S, Policy);
+
+ S += " __attribute__((ext_vector_type(";
+ if (getSizeExpr()) {
+ std::string SStr;
+ llvm::raw_string_ostream s(SStr);
+ getSizeExpr()->printPretty(s, 0, Policy);
+ S += s.str();
+ }
+ S += ")))";
+}
+
void VectorType::getAsStringInternal(std::string &S, const PrintingPolicy &Policy) const {
// FIXME: We prefer to print the size directly here, but have no way
// to get the size of the type.
@@ -1476,6 +1512,9 @@ TemplateSpecializationType::PrintTemplateArgumentList(
Args[Arg].getAsExpr()->printPretty(s, 0, Policy);
break;
}
+ case TemplateArgument::Pack:
+ assert(0 && "FIXME: Implement!");
+ break;
}
// If this is the first argument and its string representation
@@ -1566,6 +1605,30 @@ void ObjCInterfaceType::getAsStringInternal(std::string &InnerString, const Prin
InnerString = getDecl()->getIdentifier()->getName() + InnerString;
}
+void ObjCObjectPointerType::getAsStringInternal(std::string &InnerString,
+ const PrintingPolicy &Policy) const {
+ if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
+ InnerString = ' ' + InnerString;
+
+ std::string ObjCQIString;
+
+ if (getDecl())
+ ObjCQIString = getDecl()->getNameAsString();
+ else
+ ObjCQIString = "id";
+
+ if (!qual_empty()) {
+ ObjCQIString += '<';
+ for (qual_iterator I = qual_begin(), E = qual_end(); I != E; ++I) {
+ ObjCQIString += (*I)->getNameAsString();
+ if (I+1 != E)
+ ObjCQIString += ',';
+ }
+ ObjCQIString += '>';
+ }
+ InnerString = ObjCQIString + InnerString;
+}
+
void
ObjCQualifiedInterfaceType::getAsStringInternal(std::string &InnerString,
const PrintingPolicy &Policy) const {
@@ -1585,20 +1648,6 @@ ObjCQualifiedInterfaceType::getAsStringInternal(std::string &InnerString,
InnerString = ObjCQIString + InnerString;
}
-void ObjCQualifiedIdType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
- if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
- InnerString = ' ' + InnerString;
- std::string ObjCQIString = "id";
- ObjCQIString += '<';
- for (qual_iterator I = qual_begin(), E = qual_end(); I != E; ++I) {
- ObjCQIString += (*I)->getNameAsString();
- if (I+1 != E)
- ObjCQIString += ',';
- }
- ObjCQIString += '>';
- InnerString = ObjCQIString + InnerString;
-}
-
void TagType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
if (Policy.SuppressTag)
return;
OpenPOWER on IntegriCloud