summaryrefslogtreecommitdiffstats
path: root/lib/AST
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST')
-rw-r--r--lib/AST/ASTContext.cpp104
-rw-r--r--lib/AST/CXXInheritance.cpp36
-rw-r--r--lib/AST/Decl.cpp8
-rw-r--r--lib/AST/DeclBase.cpp20
-rw-r--r--lib/AST/DeclCXX.cpp12
-rw-r--r--lib/AST/DeclObjC.cpp48
-rw-r--r--lib/AST/Expr.cpp10
-rw-r--r--lib/AST/ExprCXX.cpp9
-rw-r--r--lib/AST/ExprConstant.cpp9
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp5
-rw-r--r--lib/AST/Type.cpp39
-rw-r--r--lib/AST/TypeLoc.cpp54
12 files changed, 287 insertions, 67 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 76ec852..c1bc709 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1200,43 +1200,58 @@ QualType ASTContext::getObjCGCQualType(QualType T,
return getExtQualType(TypeNode, Quals);
}
-QualType ASTContext::getNoReturnType(QualType T, bool AddNoReturn) {
+static QualType getNoReturnCallConvType(ASTContext& Context, QualType T,
+ bool AddNoReturn,
+ CallingConv CallConv) {
QualType ResultType;
if (const PointerType *Pointer = T->getAs<PointerType>()) {
QualType Pointee = Pointer->getPointeeType();
- ResultType = getNoReturnType(Pointee, AddNoReturn);
+ ResultType = getNoReturnCallConvType(Context, Pointee, AddNoReturn,
+ CallConv);
if (ResultType == Pointee)
return T;
-
- ResultType = getPointerType(ResultType);
+
+ ResultType = Context.getPointerType(ResultType);
} else if (const BlockPointerType *BlockPointer
= T->getAs<BlockPointerType>()) {
QualType Pointee = BlockPointer->getPointeeType();
- ResultType = getNoReturnType(Pointee, AddNoReturn);
+ ResultType = getNoReturnCallConvType(Context, Pointee, AddNoReturn,
+ CallConv);
if (ResultType == Pointee)
return T;
-
- ResultType = getBlockPointerType(ResultType);
- } else if (const FunctionType *F = T->getAs<FunctionType>()) {
- if (F->getNoReturnAttr() == AddNoReturn)
+
+ ResultType = Context.getBlockPointerType(ResultType);
+ } else if (const FunctionType *F = T->getAs<FunctionType>()) {
+ if (F->getNoReturnAttr() == AddNoReturn && F->getCallConv() == CallConv)
return T;
-
+
if (const FunctionNoProtoType *FNPT = dyn_cast<FunctionNoProtoType>(F)) {
- ResultType = getFunctionNoProtoType(FNPT->getResultType(), AddNoReturn);
+ ResultType = Context.getFunctionNoProtoType(FNPT->getResultType(),
+ AddNoReturn, CallConv);
} else {
const FunctionProtoType *FPT = cast<FunctionProtoType>(F);
ResultType
- = getFunctionType(FPT->getResultType(), FPT->arg_type_begin(),
- FPT->getNumArgs(), FPT->isVariadic(),
- FPT->getTypeQuals(),
- FPT->hasExceptionSpec(), FPT->hasAnyExceptionSpec(),
- FPT->getNumExceptions(), FPT->exception_begin(),
- AddNoReturn);
+ = Context.getFunctionType(FPT->getResultType(), FPT->arg_type_begin(),
+ FPT->getNumArgs(), FPT->isVariadic(),
+ FPT->getTypeQuals(),
+ FPT->hasExceptionSpec(),
+ FPT->hasAnyExceptionSpec(),
+ FPT->getNumExceptions(),
+ FPT->exception_begin(),
+ AddNoReturn, CallConv);
}
} else
return T;
-
- return getQualifiedType(ResultType, T.getLocalQualifiers());
+
+ return Context.getQualifiedType(ResultType, T.getLocalQualifiers());
+}
+
+QualType ASTContext::getNoReturnType(QualType T, bool AddNoReturn) {
+ return getNoReturnCallConvType(*this, T, AddNoReturn, T.getCallConv());
+}
+
+QualType ASTContext::getCallConvType(QualType T, CallingConv CallConv) {
+ return getNoReturnCallConvType(*this, T, T.getNoReturnAttr(), CallConv);
}
/// getComplexType - Return the uniqued reference to the type for a complex
@@ -1679,9 +1694,16 @@ QualType ASTContext::getDependentSizedExtVectorType(QualType vecType,
return QualType(New, 0);
}
+static CallingConv getCanonicalCallingConv(CallingConv CC) {
+ if (CC == CC_C)
+ return CC_Default;
+ return CC;
+}
+
/// getFunctionNoProtoType - Return a K&R style C function type like 'int()'.
///
-QualType ASTContext::getFunctionNoProtoType(QualType ResultTy, bool NoReturn) {
+QualType ASTContext::getFunctionNoProtoType(QualType ResultTy, bool NoReturn,
+ CallingConv CallConv) {
// Unique functions, to guarantee there is only one function of a particular
// structure.
llvm::FoldingSetNodeID ID;
@@ -1693,8 +1715,10 @@ QualType ASTContext::getFunctionNoProtoType(QualType ResultTy, bool NoReturn) {
return QualType(FT, 0);
QualType Canonical;
- if (!ResultTy.isCanonical()) {
- Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy), NoReturn);
+ if (!ResultTy.isCanonical() ||
+ getCanonicalCallingConv(CallConv) != CallConv) {
+ Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy), NoReturn,
+ getCanonicalCallingConv(CallConv));
// Get the new insert position for the node we care about.
FunctionNoProtoType *NewIP =
@@ -1715,7 +1739,8 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray,
unsigned NumArgs, bool isVariadic,
unsigned TypeQuals, bool hasExceptionSpec,
bool hasAnyExceptionSpec, unsigned NumExs,
- const QualType *ExArray, bool NoReturn) {
+ const QualType *ExArray, bool NoReturn,
+ CallingConv CallConv) {
// Unique functions, to guarantee there is only one function of a particular
// structure.
llvm::FoldingSetNodeID ID;
@@ -1737,7 +1762,7 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray,
// If this type isn't canonical, get the canonical version of it.
// The exception spec is not part of the canonical type.
QualType Canonical;
- if (!isCanonical) {
+ if (!isCanonical || getCanonicalCallingConv(CallConv) != CallConv) {
llvm::SmallVector<QualType, 16> CanonicalArgs;
CanonicalArgs.reserve(NumArgs);
for (unsigned i = 0; i != NumArgs; ++i)
@@ -1746,7 +1771,8 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray,
Canonical = getFunctionType(getCanonicalType(ResultTy),
CanonicalArgs.data(), NumArgs,
isVariadic, TypeQuals, false,
- false, 0, 0, NoReturn);
+ false, 0, 0, NoReturn,
+ getCanonicalCallingConv(CallConv));
// Get the new insert position for the node we care about.
FunctionProtoType *NewIP =
@@ -1763,7 +1789,7 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray,
NumExs*sizeof(QualType), TypeAlignment);
new (FTP) FunctionProtoType(ResultTy, ArgArray, NumArgs, isVariadic,
TypeQuals, hasExceptionSpec, hasAnyExceptionSpec,
- ExArray, NumExs, Canonical, NoReturn);
+ ExArray, NumExs, Canonical, NoReturn, CallConv);
Types.push_back(FTP);
FunctionProtoTypes.InsertNode(FTP, InsertPos);
return QualType(FTP, 0);
@@ -2101,7 +2127,8 @@ QualType ASTContext::getObjCObjectPointerType(QualType InterfaceT,
// No Match;
ObjCObjectPointerType *QType = new (*this, TypeAlignment)
- ObjCObjectPointerType(Canonical, InterfaceT, Protocols, NumProtocols);
+ ObjCObjectPointerType(*this, Canonical, InterfaceT, Protocols,
+ NumProtocols);
Types.push_back(QType);
ObjCObjectPointerTypes.InsertNode(QType, InsertPos);
@@ -2135,7 +2162,7 @@ QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
}
ObjCInterfaceType *QType = new (*this, TypeAlignment)
- ObjCInterfaceType(Canonical, const_cast<ObjCInterfaceDecl*>(Decl),
+ ObjCInterfaceType(*this, Canonical, const_cast<ObjCInterfaceDecl*>(Decl),
Protocols, NumProtocols);
Types.push_back(QType);
@@ -3733,8 +3760,8 @@ void ASTContext::setObjCConstantStringInterface(ObjCInterfaceDecl *Decl) {
/// \brief Retrieve the template name that corresponds to a non-empty
/// lookup.
-TemplateName ASTContext::getOverloadedTemplateName(NamedDecl * const *Begin,
- NamedDecl * const *End) {
+TemplateName ASTContext::getOverloadedTemplateName(UnresolvedSetIterator Begin,
+ UnresolvedSetIterator End) {
unsigned size = End - Begin;
assert(size > 1 && "set is not overloaded!");
@@ -3743,7 +3770,7 @@ TemplateName ASTContext::getOverloadedTemplateName(NamedDecl * const *Begin,
OverloadedTemplateStorage *OT = new(memory) OverloadedTemplateStorage(size);
NamedDecl **Storage = OT->getStorage();
- for (NamedDecl * const *I = Begin; I != End; ++I) {
+ for (UnresolvedSetIterator I = Begin; I != End; ++I) {
NamedDecl *D = *I;
assert(isa<FunctionTemplateDecl>(D) ||
(isa<UsingShadowDecl>(D) &&
@@ -4211,6 +4238,10 @@ bool ASTContext::typesAreCompatible(QualType LHS, QualType RHS) {
return !mergeTypes(LHS, RHS).isNull();
}
+static bool isSameCallingConvention(CallingConv lcc, CallingConv rcc) {
+ return (getCanonicalCallingConv(lcc) == getCanonicalCallingConv(rcc));
+}
+
QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs) {
const FunctionType *lbase = lhs->getAs<FunctionType>();
const FunctionType *rbase = rhs->getAs<FunctionType>();
@@ -4232,6 +4263,11 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs) {
allLTypes = false;
if (NoReturn != rbase->getNoReturnAttr())
allRTypes = false;
+ CallingConv lcc = lbase->getCallConv();
+ CallingConv rcc = rbase->getCallConv();
+ // Compatible functions must have compatible calling conventions
+ if (!isSameCallingConvention(lcc, rcc))
+ return QualType();
if (lproto && rproto) { // two C99 style function prototypes
assert(!lproto->hasExceptionSpec() && !rproto->hasExceptionSpec() &&
@@ -4267,7 +4303,7 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs) {
if (allRTypes) return rhs;
return getFunctionType(retType, types.begin(), types.size(),
lproto->isVariadic(), lproto->getTypeQuals(),
- NoReturn);
+ NoReturn, lcc);
}
if (lproto) allRTypes = false;
@@ -4294,12 +4330,12 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs) {
if (allRTypes) return rhs;
return getFunctionType(retType, proto->arg_type_begin(),
proto->getNumArgs(), proto->isVariadic(),
- proto->getTypeQuals(), NoReturn);
+ proto->getTypeQuals(), NoReturn, lcc);
}
if (allLTypes) return lhs;
if (allRTypes) return rhs;
- return getFunctionNoProtoType(retType, NoReturn);
+ return getFunctionNoProtoType(retType, NoReturn, lcc);
}
QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index 92a58b7..7208328 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -145,7 +145,11 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches,
void *UserData,
CXXBasePaths &Paths) const {
bool FoundPath = false;
-
+
+ // The access of the path down to this record.
+ AccessSpecifier AccessToHere = Paths.ScratchPath.Access;
+ bool IsFirstStep = Paths.ScratchPath.empty();
+
ASTContext &Context = getASTContext();
for (base_class_const_iterator BaseSpec = bases_begin(),
BaseSpecEnd = bases_end(); BaseSpec != BaseSpecEnd; ++BaseSpec) {
@@ -189,10 +193,31 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches,
else
Element.SubobjectNumber = Subobjects.second;
Paths.ScratchPath.push_back(Element);
+
+ // Calculate the "top-down" access to this base class.
+ // The spec actually describes this bottom-up, but top-down is
+ // equivalent because the definition works out as follows:
+ // 1. Write down the access along each step in the inheritance
+ // chain, followed by the access of the decl itself.
+ // For example, in
+ // class A { public: int foo; };
+ // class B : protected A {};
+ // class C : public B {};
+ // class D : private C {};
+ // we would write:
+ // private public protected public
+ // 2. If 'private' appears anywhere except far-left, access is denied.
+ // 3. Otherwise, overall access is determined by the most restrictive
+ // access in the sequence.
+ if (IsFirstStep)
+ Paths.ScratchPath.Access = BaseSpec->getAccessSpecifier();
+ else
+ Paths.ScratchPath.Access
+ = MergeAccess(AccessToHere, BaseSpec->getAccessSpecifier());
}
if (BaseMatches(BaseSpec, Paths.ScratchPath, UserData)) {
- // We've found a path that terminates that this base.
+ // We've found a path that terminates at this base.
FoundPath = true;
if (Paths.isRecordingPaths()) {
// We have a path. Make a copy of it before moving on.
@@ -223,13 +248,18 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches,
// Pop this base specifier off the current path (if we're
// collecting paths).
- if (Paths.isRecordingPaths())
+ if (Paths.isRecordingPaths()) {
Paths.ScratchPath.pop_back();
+ }
+
// If we set a virtual earlier, and this isn't a path, forget it again.
if (SetVirtual && !FoundPath) {
Paths.DetectedVirtual = 0;
}
}
+
+ // Reset the scratch path access.
+ Paths.ScratchPath.Access = AccessToHere;
return FoundPath;
}
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index e77661a..794b14a 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -629,9 +629,13 @@ VarDecl::~VarDecl() {
}
SourceRange VarDecl::getSourceRange() const {
+ SourceLocation Start = getTypeSpecStartLoc();
+ if (Start.isInvalid())
+ Start = getLocation();
+
if (getInit())
- return SourceRange(getLocation(), getInit()->getLocEnd());
- return SourceRange(getLocation(), getLocation());
+ return SourceRange(Start, getInit()->getLocEnd());
+ return SourceRange(Start, getLocation());
}
bool VarDecl::isOutOfLine() const {
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 3afb4e4..84aa81c 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -102,6 +102,17 @@ bool Decl::isFunctionOrFunctionTemplate() const {
return isa<FunctionDecl>(this) || isa<FunctionTemplateDecl>(this);
}
+bool Decl::isDefinedOutsideFunctionOrMethod() const {
+ for (const DeclContext *DC = getDeclContext();
+ DC && !DC->isTranslationUnit();
+ DC = DC->getParent())
+ if (DC->isFunctionOrMethod())
+ return false;
+
+ return true;
+}
+
+
//===----------------------------------------------------------------------===//
// PrettyStackTraceDecl Implementation
//===----------------------------------------------------------------------===//
@@ -399,8 +410,13 @@ SourceLocation Decl::getBodyRBrace() const {
#ifndef NDEBUG
void Decl::CheckAccessDeclContext() const {
- // If the decl is the toplevel translation unit or if we're not in a
- // record decl context, we don't need to check anything.
+ // Suppress this check if any of the following hold:
+ // 1. this is the translation unit (and thus has no parent)
+ // 2. this is a template parameter (and thus doesn't belong to its context)
+ // 3. this is a ParmVarDecl (which can be in a record context during
+ // the brief period between its creation and the creation of the
+ // FunctionDecl)
+ // 4. the context is not a record
if (isa<TranslationUnitDecl>(this) ||
!isa<CXXRecordDecl>(getDeclContext()))
return;
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 1cce35c..fe6064d 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -312,8 +312,9 @@ void
CXXRecordDecl::collectConversionFunctions(
llvm::SmallPtrSet<CanQualType, 8>& ConversionsTypeSet) const
{
- const UnresolvedSet *Cs = getConversionFunctions();
- for (UnresolvedSet::iterator I = Cs->begin(), E = Cs->end(); I != E; ++I) {
+ const UnresolvedSetImpl *Cs = getConversionFunctions();
+ for (UnresolvedSetImpl::iterator I = Cs->begin(), E = Cs->end();
+ I != E; ++I) {
NamedDecl *TopConv = *I;
CanQualType TConvType;
if (FunctionTemplateDecl *TConversionTemplate =
@@ -344,10 +345,11 @@ CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD,
bool inTopClass = (RD == this);
QualType ClassType = getASTContext().getTypeDeclType(this);
if (const RecordType *Record = ClassType->getAs<RecordType>()) {
- const UnresolvedSet *Cs
+ const UnresolvedSetImpl *Cs
= cast<CXXRecordDecl>(Record->getDecl())->getConversionFunctions();
- for (UnresolvedSet::iterator I = Cs->begin(), E = Cs->end(); I != E; ++I) {
+ for (UnresolvedSetImpl::iterator I = Cs->begin(), E = Cs->end();
+ I != E; ++I) {
NamedDecl *Conv = *I;
// Only those conversions not exact match of conversions in current
// class are candidateconversion routines.
@@ -410,7 +412,7 @@ CXXRecordDecl::getNestedVisibleConversionFunctions(CXXRecordDecl *RD,
/// getVisibleConversionFunctions - get all conversion functions visible
/// in current class; including conversion function templates.
-const UnresolvedSet *CXXRecordDecl::getVisibleConversionFunctions() {
+const UnresolvedSetImpl *CXXRecordDecl::getVisibleConversionFunctions() {
// If root class, all conversions are visible.
if (bases_begin() == bases_end())
return &Conversions;
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 2506f27..ffda505 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -37,6 +37,21 @@ void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {
memcpy(List, InList, sizeof(void*)*Elts);
}
+void ObjCProtocolList::set(ObjCProtocolDecl* const* InList, unsigned Elts,
+ const SourceLocation *Locs, ASTContext &Ctx) {
+ if (Elts == 0)
+ return;
+
+ Locations = new (Ctx) SourceLocation[Elts];
+ memcpy(Locations, Locs, sizeof(SourceLocation) * Elts);
+ set(InList, Elts, Ctx);
+}
+
+void ObjCProtocolList::Destroy(ASTContext &Ctx) {
+ Ctx.Deallocate(Locations);
+ Locations = 0;
+ ObjCList<ObjCProtocolDecl>::Destroy(Ctx);
+}
//===----------------------------------------------------------------------===//
// ObjCInterfaceDecl
@@ -141,16 +156,18 @@ ObjCContainerDecl::FindPropertyVisibleInPrimaryClass(
void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
+ const SourceLocation *Locs,
ASTContext &C)
{
if (ReferencedProtocols.empty()) {
- ReferencedProtocols.set(ExtList, ExtNum, C);
+ ReferencedProtocols.set(ExtList, ExtNum, Locs, C);
return;
}
// Check for duplicate protocol in class's protocol list.
// This is (O)2. But it is extremely rare and number of protocols in
// class or its extension are very few.
llvm::SmallVector<ObjCProtocolDecl*, 8> ProtocolRefs;
+ llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
for (unsigned i = 0; i < ExtNum; i++) {
bool protocolExists = false;
ObjCProtocolDecl *ProtoInExtension = ExtList[i];
@@ -164,18 +181,23 @@ void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
}
// Do we want to warn on a protocol in extension class which
// already exist in the class? Probably not.
- if (!protocolExists)
+ if (!protocolExists) {
ProtocolRefs.push_back(ProtoInExtension);
+ ProtocolLocs.push_back(Locs[i]);
+ }
}
if (ProtocolRefs.empty())
return;
// Merge ProtocolRefs into class's protocol list;
+ protocol_loc_iterator pl = protocol_loc_begin();
for (protocol_iterator p = protocol_begin(), e = protocol_end();
- p != e; p++)
+ p != e; ++p, ++pl) {
ProtocolRefs.push_back(*p);
+ ProtocolLocs.push_back(*pl);
+ }
ReferencedProtocols.Destroy(C);
unsigned NumProtoRefs = ProtocolRefs.size();
- setProtocolList((ObjCProtocolDecl**)&ProtocolRefs[0], NumProtoRefs, C);
+ setProtocolList(ProtocolRefs.data(), NumProtoRefs, ProtocolLocs.data(), C);
}
ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable(IdentifierInfo *ID,
@@ -627,9 +649,9 @@ SourceRange ObjCClassDecl::getSourceRange() const {
ObjCForwardProtocolDecl::
ObjCForwardProtocolDecl(DeclContext *DC, SourceLocation L,
ObjCProtocolDecl *const *Elts, unsigned nElts,
- ASTContext &C)
+ const SourceLocation *Locs, ASTContext &C)
: Decl(ObjCForwardProtocol, DC, L) {
- ReferencedProtocols.set(Elts, nElts, C);
+ ReferencedProtocols.set(Elts, nElts, Locs, C);
}
@@ -637,8 +659,9 @@ ObjCForwardProtocolDecl *
ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
ObjCProtocolDecl *const *Elts,
- unsigned NumElts) {
- return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, C);
+ unsigned NumElts,
+ const SourceLocation *Locs) {
+ return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts, Locs, C);
}
void ObjCForwardProtocolDecl::Destroy(ASTContext &C) {
@@ -651,9 +674,11 @@ void ObjCForwardProtocolDecl::Destroy(ASTContext &C) {
//===----------------------------------------------------------------------===//
ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,
+ SourceLocation AtLoc,
+ SourceLocation ClassNameLoc,
+ SourceLocation CategoryNameLoc,
IdentifierInfo *Id) {
- return new (C) ObjCCategoryDecl(DC, L, Id);
+ return new (C) ObjCCategoryDecl(DC, AtLoc, ClassNameLoc, CategoryNameLoc, Id);
}
ObjCCategoryImplDecl *ObjCCategoryDecl::getImplementation() const {
@@ -765,9 +790,10 @@ ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
IdentifierInfo *Id,
+ SourceLocation AtLoc,
QualType T,
PropertyControl propControl) {
- return new (C) ObjCPropertyDecl(DC, L, Id, T);
+ return new (C) ObjCPropertyDecl(DC, L, Id, AtLoc, T);
}
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 4c3046b..fa44b51 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -98,10 +98,12 @@ void DeclRefExpr::computeDependence() {
// initialized with an expression that is value-dependent.
else if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
if (Var->getType()->isIntegralType() &&
- Var->getType().getCVRQualifiers() == Qualifiers::Const &&
- Var->getInit() &&
- Var->getInit()->isValueDependent())
- ValueDependent = true;
+ Var->getType().getCVRQualifiers() == Qualifiers::Const) {
+ const VarDecl *Def = 0;
+ if (const Expr *Init = Var->getDefinition(Def))
+ if (Init->isValueDependent())
+ ValueDependent = true;
+ }
}
// (TD) - a nested-name-specifier or a qualified-id that names a
// member of an unknown specialization.
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 81584b7..a6574ef 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -135,10 +135,11 @@ UnresolvedLookupExpr::Create(ASTContext &C, bool Dependent,
return ULE;
}
-bool UnresolvedLookupExpr::ComputeDependence(NamedDecl * const *Begin,
- NamedDecl * const *End,
- const TemplateArgumentListInfo *Args) {
- for (NamedDecl * const *I = Begin; I != End; ++I)
+bool UnresolvedLookupExpr::
+ ComputeDependence(UnresolvedSetImpl::const_iterator Begin,
+ UnresolvedSetImpl::const_iterator End,
+ const TemplateArgumentListInfo *Args) {
+ for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I)
if ((*I)->getDeclContext()->isDependentContext())
return true;
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index dfff209..086249c 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -506,7 +506,9 @@ APValue PointerExprEvaluator::VisitCastExpr(CastExpr* E) {
APValue PointerExprEvaluator::VisitCallExpr(CallExpr *E) {
if (E->isBuiltinCall(Info.Ctx) ==
- Builtin::BI__builtin___CFStringMakeConstantString)
+ Builtin::BI__builtin___CFStringMakeConstantString ||
+ E->isBuiltinCall(Info.Ctx) ==
+ Builtin::BI__builtin___NSStringMakeConstantString)
return APValue(E);
return APValue();
}
@@ -971,6 +973,8 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
case Builtin::BI__builtin_object_size: {
const Expr *Arg = E->getArg(0)->IgnoreParens();
Expr::EvalResult Base;
+
+ // TODO: Perhaps we should let LLVM lower this?
if (Arg->EvaluateAsAny(Base, Info.Ctx)
&& Base.Val.getKind() == APValue::LValue
&& !Base.HasSideEffects)
@@ -992,7 +996,8 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
}
}
- // TODO: Perhaps we should let LLVM lower this?
+ // If evaluating the argument has side-effects we can't determine
+ // the size of the object and lower it to unknown now.
if (E->getArg(0)->HasSideEffects(Info.Ctx)) {
if (E->getArg(1)->EvaluateAsInt(Info.Ctx).getZExtValue() <= 1)
return Success(-1ULL, E);
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index cfd89ea..0aa0180 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -119,6 +119,11 @@ ASTRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD,
return;
}
}
+ if (i->isVirtual()) {
+ SelectPrimaryVBase(Base, FirstPrimary);
+ if (PrimaryBase.getBase())
+ return;
+ }
}
}
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index e0055f1..edfb580 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -339,6 +339,25 @@ const RecordType *Type::getAsUnionType() const {
return 0;
}
+ObjCInterfaceType::ObjCInterfaceType(ASTContext &Ctx, QualType Canonical,
+ ObjCInterfaceDecl *D,
+ ObjCProtocolDecl **Protos, unsigned NumP) :
+ Type(ObjCInterface, Canonical, /*Dependent=*/false),
+ Decl(D), Protocols(0), NumProtocols(NumP)
+{
+ if (NumProtocols) {
+ Protocols = new (Ctx) ObjCProtocolDecl*[NumProtocols];
+ memcpy(Protocols, Protos, NumProtocols * sizeof(*Protocols));
+ }
+}
+
+void ObjCInterfaceType::Destroy(ASTContext& C) {
+ if (Protocols)
+ C.Deallocate(Protocols);
+ this->~ObjCInterfaceType();
+ C.Deallocate(this);
+}
+
const ObjCInterfaceType *Type::getAsObjCQualifiedInterfaceType() const {
// There is no sugar for ObjCInterfaceType's, just return the canonical
// type pointer if it is the right class. There is no typedef information to
@@ -353,6 +372,26 @@ bool Type::isObjCQualifiedInterfaceType() const {
return getAsObjCQualifiedInterfaceType() != 0;
}
+ObjCObjectPointerType::ObjCObjectPointerType(ASTContext &Ctx,
+ QualType Canonical, QualType T,
+ ObjCProtocolDecl **Protos,
+ unsigned NumP) :
+ Type(ObjCObjectPointer, Canonical, /*Dependent=*/false),
+ PointeeType(T), Protocols(NULL), NumProtocols(NumP)
+{
+ if (NumProtocols) {
+ Protocols = new (Ctx) ObjCProtocolDecl*[NumProtocols];
+ memcpy(Protocols, Protos, NumProtocols * sizeof(*Protocols));
+ }
+}
+
+void ObjCObjectPointerType::Destroy(ASTContext& C) {
+ if (Protocols)
+ C.Deallocate(Protocols);
+ this->~ObjCObjectPointerType();
+ C.Deallocate(this);
+}
+
const ObjCObjectPointerType *Type::getAsObjCQualifiedIdType() const {
// There is no sugar for ObjCQualifiedIdType's, just return the canonical
// type pointer if it is the right class.
diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp
index 0840c52..fd9fbc1 100644
--- a/lib/AST/TypeLoc.cpp
+++ b/lib/AST/TypeLoc.cpp
@@ -14,6 +14,7 @@
#include "llvm/Support/raw_ostream.h"
#include "clang/AST/TypeLocVisitor.h"
#include "clang/AST/Expr.h"
+#include "llvm/Support/ErrorHandling.h"
using namespace clang;
//===----------------------------------------------------------------------===//
@@ -135,3 +136,56 @@ SourceRange TypeOfExprTypeLoc::getSourceRange() const {
return SourceRange(getTypeofLoc(),
getUnderlyingExpr()->getSourceRange().getEnd());
}
+
+
+TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
+ if (needsExtraLocalData())
+ return static_cast<TypeSpecifierType>(getWrittenBuiltinSpecs().Type);
+ else {
+ switch (getTypePtr()->getKind()) {
+ case BuiltinType::Void:
+ return TST_void;
+ case BuiltinType::Bool:
+ return TST_bool;
+ case BuiltinType::Char_U:
+ case BuiltinType::Char_S:
+ return TST_char;
+ case BuiltinType::Char16:
+ return TST_char16;
+ case BuiltinType::Char32:
+ return TST_char32;
+ case BuiltinType::WChar:
+ return TST_wchar;
+ case BuiltinType::UndeducedAuto:
+ return TST_auto;
+
+ case BuiltinType::UChar:
+ case BuiltinType::UShort:
+ case BuiltinType::UInt:
+ case BuiltinType::ULong:
+ case BuiltinType::ULongLong:
+ case BuiltinType::UInt128:
+ case BuiltinType::SChar:
+ case BuiltinType::Short:
+ case BuiltinType::Int:
+ case BuiltinType::Long:
+ case BuiltinType::LongLong:
+ case BuiltinType::Int128:
+ case BuiltinType::Float:
+ case BuiltinType::Double:
+ case BuiltinType::LongDouble:
+ llvm_unreachable("Builtin type needs extra local data!");
+ // Fall through, if the impossible happens.
+
+ case BuiltinType::NullPtr:
+ case BuiltinType::Overload:
+ case BuiltinType::Dependent:
+ case BuiltinType::ObjCId:
+ case BuiltinType::ObjCClass:
+ case BuiltinType::ObjCSel:
+ return TST_unspecified;
+ }
+ }
+
+ return TST_unspecified;
+}
OpenPOWER on IntegriCloud