diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/TypeLoc.cpp | 56 | ||||
-rw-r--r-- | lib/Frontend/PCHReader.cpp | 8 | ||||
-rw-r--r-- | lib/Frontend/PCHWriter.cpp | 8 | ||||
-rw-r--r-- | lib/Parse/DeclSpec.cpp | 19 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 15 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 6 |
6 files changed, 109 insertions, 3 deletions
diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp index 0840c52b4c..6da2ab0dee 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,58 @@ 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::Float: + return TST_float; + case BuiltinType::Double: + case BuiltinType::LongDouble: + return TST_double; + 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: + 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; +} diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index 1f23bd2141..77fa11e3e3 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -2042,7 +2042,13 @@ void TypeLocReader::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { // nothing to do } void TypeLocReader::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { - TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setBuiltinLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + if (TL.needsExtraLocalData()) { + TL.setWrittenTypeSpec(static_cast<DeclSpec::TST>(Record[Idx++])); + TL.setWrittenSignSpec(static_cast<DeclSpec::TSS>(Record[Idx++])); + TL.setWrittenWidthSpec(static_cast<DeclSpec::TSW>(Record[Idx++])); + TL.setModeAttr(Record[Idx++]); + } } void TypeLocReader::VisitComplexTypeLoc(ComplexTypeLoc TL) { TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 21e09744e3..97cd84f447 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -277,7 +277,13 @@ void TypeLocWriter::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { // nothing to do } void TypeLocWriter::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { - Writer.AddSourceLocation(TL.getNameLoc(), Record); + Writer.AddSourceLocation(TL.getBuiltinLoc(), Record); + if (TL.needsExtraLocalData()) { + Record.push_back(TL.getWrittenTypeSpec()); + Record.push_back(TL.getWrittenSignSpec()); + Record.push_back(TL.getWrittenWidthSpec()); + Record.push_back(TL.hasModeAttr()); + } } void TypeLocWriter::VisitComplexTypeLoc(ComplexTypeLoc TL) { Writer.AddSourceLocation(TL.getNameLoc(), Record); diff --git a/lib/Parse/DeclSpec.cpp b/lib/Parse/DeclSpec.cpp index f52d8b9856..9e5f5a2ac0 100644 --- a/lib/Parse/DeclSpec.cpp +++ b/lib/Parse/DeclSpec.cpp @@ -373,11 +373,30 @@ void DeclSpec::setProtocolQualifiers(const ActionBase::DeclPtrTy *Protos, ProtocolLAngleLoc = LAngleLoc; } +void DeclSpec::SaveWrittenBuiltinSpecs() { + writtenBS.Sign = getTypeSpecSign(); + writtenBS.Width = getTypeSpecWidth(); + writtenBS.Type = getTypeSpecType(); + // Search the list of attributes for the presence of a mode attribute. + writtenBS.ModeAttr = false; + AttributeList* attrs = getAttributes(); + while (attrs) { + if (attrs->getKind() == AttributeList::AT_mode) { + writtenBS.ModeAttr = true; + break; + } + attrs = attrs->getNext(); + } +} + /// Finish - This does final analysis of the declspec, rejecting things like /// "_Imaginary" (lacking an FP type). This returns a diagnostic to issue or /// diag::NUM_DIAGNOSTICS if there is no error. After calling this method, /// DeclSpec is guaranteed self-consistent, even if an error occurred. void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) { + // Before possibly changing their values, save specs as written. + SaveWrittenBuiltinSpecs(); + // Check the type specifier components first. SourceManager &SrcMgr = PP.getSourceManager(); diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 9515834bb8..906576115a 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -1374,6 +1374,21 @@ namespace { Sema::GetTypeFromParser(DS.getTypeRep(), &TInfo); TL.setUnderlyingTInfo(TInfo); } + void VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { + // By default, use the source location of the type specifier. + TL.setBuiltinLoc(DS.getTypeSpecTypeLoc()); + if (TL.needsExtraLocalData()) { + // Set info for the written builtin specifiers. + TL.getWrittenBuiltinSpecs() = DS.getWrittenBuiltinSpecs(); + // Try to have a meaningful source location. + if (TL.getWrittenSignSpec() != TSS_unspecified) + // Sign spec loc overrides the others (e.g., 'unsigned long'). + TL.setBuiltinLoc(DS.getTypeSpecSignLoc()); + else if (TL.getWrittenWidthSpec() != TSW_unspecified) + // Width spec loc overrides type spec loc (e.g., 'short int'). + TL.setBuiltinLoc(DS.getTypeSpecWidthLoc()); + } + } void VisitTypeLoc(TypeLoc TL) { // FIXME: add other typespec types and change this to an assert. TL.initialize(DS.getTypeSpecTypeLoc()); diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 41f465f595..aba6455df3 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -2138,7 +2138,11 @@ QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) { template<typename Derived> QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB, BuiltinTypeLoc T) { - return TransformTypeSpecType(TLB, T); + BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T.getType()); + NewT.setBuiltinLoc(T.getBuiltinLoc()); + if (T.needsExtraLocalData()) + NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs(); + return T.getType(); } template<typename Derived> |